@blocklet/pages-kit-block-studio 0.4.32 → 0.4.34
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/components/create-resource.js +2 -2
- package/lib/cjs/constants/new-block-template/index.js +2 -14
- package/lib/cjs/middlewares/init-block-studio-router.js +15 -21
- package/lib/cjs/middlewares/init-resource-router.js +34 -42
- package/lib/cjs/plugins/vite-plugin-block-studio.js +107 -86
- package/lib/cjs/plugins/vite-plugin-html-transform.js +13 -24
- package/lib/cjs/plugins/vite-plugin-remote-script-localizer.js +87 -103
- package/lib/cjs/tsconfig.tsbuildinfo +1 -1
- package/lib/cjs/utils/build-lib.js +62 -74
- package/lib/cjs/utils/generate-wrapper-code.js +366 -120
- package/lib/cjs/utils/helper.js +9 -19
- package/lib/esm/components/create-resource.js +2 -2
- package/lib/esm/constants/new-block-template/index.js +2 -14
- package/lib/esm/middlewares/init-block-studio-router.js +15 -21
- package/lib/esm/middlewares/init-resource-router.js +34 -42
- package/lib/esm/plugins/vite-plugin-block-studio.js +107 -86
- package/lib/esm/plugins/vite-plugin-html-transform.js +13 -24
- package/lib/esm/plugins/vite-plugin-remote-script-localizer.js +87 -103
- package/lib/esm/tsconfig.tsbuildinfo +1 -1
- package/lib/esm/utils/build-lib.js +62 -74
- package/lib/esm/utils/generate-wrapper-code.js +366 -120
- package/lib/esm/utils/helper.js +9 -19
- package/lib/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -32,74 +32,66 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
36
|
exports.generateWrapperCode = generateWrapperCode;
|
|
46
37
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
47
|
-
function generateWrapperCode(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
38
|
+
async function generateWrapperCode({ project, state, version }) {
|
|
39
|
+
const projectName = (project.name || project.id).toLowerCase().replaceAll(/[^a-z0-9]/g, '-');
|
|
40
|
+
const packageName = `@pages-kit-project/${projectName}`;
|
|
41
|
+
const packageJson = JSON.stringify({
|
|
42
|
+
name: packageName,
|
|
43
|
+
version: version || '0.0.1',
|
|
44
|
+
main: 'index.cjs',
|
|
45
|
+
module: 'index.js',
|
|
46
|
+
types: 'index.d.ts',
|
|
47
|
+
peerDependencies: {
|
|
48
|
+
'@blocklet/pages-kit-runtime': 'latest',
|
|
49
|
+
'@blocklet/pages-kit-inner-components': 'latest',
|
|
50
|
+
'@blocklet/pages-kit': 'latest',
|
|
51
|
+
'@blocklet/uploader-server': 'latest',
|
|
52
|
+
'@arcblock/ux': 'latest',
|
|
53
|
+
'@mui/material': '5.16.14',
|
|
54
|
+
},
|
|
55
|
+
dependencies: {
|
|
56
|
+
'@blocklet/pages-kit-runtime': 'latest',
|
|
57
|
+
'@blocklet/pages-kit-inner-components': 'latest',
|
|
58
|
+
'@blocklet/pages-kit': 'latest',
|
|
59
|
+
'@blocklet/uploader-server': 'latest',
|
|
60
|
+
'@arcblock/ux': 'latest',
|
|
61
|
+
'@mui/material': '5.16.14',
|
|
62
|
+
},
|
|
63
|
+
exports: {
|
|
64
|
+
'.': {
|
|
65
|
+
require: './index.cjs',
|
|
66
|
+
import: './index.js',
|
|
67
|
+
types: './index.d.ts',
|
|
64
68
|
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
'@blocklet/uploader-server': 'latest',
|
|
70
|
-
'@arcblock/ux': 'latest',
|
|
71
|
-
'@mui/material': '5.16.14',
|
|
69
|
+
'./client': {
|
|
70
|
+
require: './client.cjs',
|
|
71
|
+
import: './client.js',
|
|
72
|
+
types: './client.d.ts',
|
|
72
73
|
},
|
|
73
|
-
|
|
74
|
-
'.'
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
types: './index.d.ts',
|
|
78
|
-
},
|
|
79
|
-
'./client': {
|
|
80
|
-
require: './client.cjs',
|
|
81
|
-
import: './client.js',
|
|
82
|
-
types: './client.d.ts',
|
|
83
|
-
},
|
|
84
|
-
'./middleware': {
|
|
85
|
-
require: './middleware.cjs',
|
|
86
|
-
import: './middleware.js',
|
|
87
|
-
types: './middleware.d.ts',
|
|
88
|
-
},
|
|
89
|
-
'./data.json': './data.json',
|
|
74
|
+
'./middleware': {
|
|
75
|
+
require: './middleware.cjs',
|
|
76
|
+
import: './middleware.js',
|
|
77
|
+
types: './middleware.d.ts',
|
|
90
78
|
},
|
|
91
|
-
|
|
92
|
-
|
|
79
|
+
'./data.json': './data.json',
|
|
80
|
+
},
|
|
81
|
+
}, null, 2);
|
|
82
|
+
const client = `\
|
|
93
83
|
import PageRenderComponent, { RuntimeProps, RuntimeType } from '@blocklet/pages-kit-runtime/client';
|
|
94
84
|
|
|
95
85
|
export type { RuntimeProps, RuntimeType };
|
|
96
86
|
|
|
97
87
|
${generatePageDataTypes(state)}
|
|
98
88
|
|
|
89
|
+
${generatePageDataJsonSchemas(state)}
|
|
90
|
+
|
|
99
91
|
export default PageRenderComponent;
|
|
100
92
|
`;
|
|
101
|
-
|
|
102
|
-
|
|
93
|
+
const index = client;
|
|
94
|
+
const middleware = `
|
|
103
95
|
import { Router } from 'express';
|
|
104
96
|
import axios from 'axios';
|
|
105
97
|
import { Component } from '@blocklet/sdk';
|
|
@@ -222,66 +214,71 @@ router.post('/api/components/preload', async (req, res) => {
|
|
|
222
214
|
|
|
223
215
|
export default router;
|
|
224
216
|
`;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
return [
|
|
245
|
-
{
|
|
246
|
-
fileName: 'data.json',
|
|
247
|
-
content: data,
|
|
248
|
-
},
|
|
249
|
-
];
|
|
250
|
-
}
|
|
251
|
-
const cjs = ts.transpileModule(content, {
|
|
252
|
-
fileName,
|
|
253
|
-
compilerOptions: Object.assign(Object.assign({}, compilerOptions), { module: ts.ModuleKind.CommonJS }),
|
|
254
|
-
});
|
|
255
|
-
const esm = ts.transpileModule(content, {
|
|
256
|
-
fileName,
|
|
257
|
-
compilerOptions: Object.assign(Object.assign({}, compilerOptions), { module: ts.ModuleKind.ESNext }),
|
|
258
|
-
});
|
|
259
|
-
// Generate proper type declarations
|
|
260
|
-
// const dts = ts.transpileModule(content, {
|
|
261
|
-
// fileName,
|
|
262
|
-
// compilerOptions: {
|
|
263
|
-
// ...compilerOptions,
|
|
264
|
-
// declaration: true,
|
|
265
|
-
// emitDeclarationOnly: true,
|
|
266
|
-
// },
|
|
267
|
-
// });
|
|
217
|
+
const data = JSON.stringify({
|
|
218
|
+
project,
|
|
219
|
+
state,
|
|
220
|
+
}, null, 2);
|
|
221
|
+
const tsFiles = [
|
|
222
|
+
{ fileName: 'index.ts', content: index },
|
|
223
|
+
{ fileName: 'client.ts', content: client },
|
|
224
|
+
{ fileName: 'middleware.ts', content: middleware },
|
|
225
|
+
{ fileName: 'data.json', content: data },
|
|
226
|
+
];
|
|
227
|
+
const ts = await Promise.resolve().then(() => __importStar(require('typescript')));
|
|
228
|
+
const compilerOptions = {
|
|
229
|
+
jsx: ts.JsxEmit.React,
|
|
230
|
+
esModuleInterop: true,
|
|
231
|
+
skipLibCheck: true,
|
|
232
|
+
declaration: true,
|
|
233
|
+
};
|
|
234
|
+
const result = (await Promise.all(tsFiles.map(async ({ fileName, content }) => {
|
|
235
|
+
if (fileName === 'data.json') {
|
|
268
236
|
return [
|
|
269
237
|
{
|
|
270
|
-
fileName:
|
|
271
|
-
content:
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
fileName: fileName.replace(/\.ts$/, '.js'),
|
|
275
|
-
content: esm.outputText,
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
fileName: fileName.replace(/\.ts$/, '.d.ts'),
|
|
279
|
-
content, // Fallback to original content if declaration fails
|
|
238
|
+
fileName: 'data.json',
|
|
239
|
+
content: data,
|
|
280
240
|
},
|
|
281
241
|
];
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
242
|
+
}
|
|
243
|
+
const cjs = ts.transpileModule(content, {
|
|
244
|
+
fileName,
|
|
245
|
+
compilerOptions: {
|
|
246
|
+
...compilerOptions,
|
|
247
|
+
module: ts.ModuleKind.CommonJS,
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
const esm = ts.transpileModule(content, {
|
|
251
|
+
fileName,
|
|
252
|
+
compilerOptions: {
|
|
253
|
+
...compilerOptions,
|
|
254
|
+
module: ts.ModuleKind.ESNext,
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
// Generate proper type declarations
|
|
258
|
+
// const dts = ts.transpileModule(content, {
|
|
259
|
+
// fileName,
|
|
260
|
+
// compilerOptions: {
|
|
261
|
+
// ...compilerOptions,
|
|
262
|
+
// declaration: true,
|
|
263
|
+
// emitDeclarationOnly: true,
|
|
264
|
+
// },
|
|
265
|
+
// });
|
|
266
|
+
return [
|
|
267
|
+
{
|
|
268
|
+
fileName: fileName.replace(/\.ts$/, '.cjs'),
|
|
269
|
+
content: cjs.outputText,
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
fileName: fileName.replace(/\.ts$/, '.js'),
|
|
273
|
+
content: esm.outputText,
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
fileName: fileName.replace(/\.ts$/, '.d.ts'),
|
|
277
|
+
content, // Fallback to original content if declaration fails
|
|
278
|
+
},
|
|
279
|
+
];
|
|
280
|
+
}))).flat();
|
|
281
|
+
return [...result, { fileName: 'package.json', content: packageJson }];
|
|
285
282
|
}
|
|
286
283
|
const basicComponentSectionTypes = {
|
|
287
284
|
iframe: `
|
|
@@ -325,6 +322,44 @@ function getCustomComponentPropertyType(type) {
|
|
|
325
322
|
}
|
|
326
323
|
const ALLOWED_PROPERTY_TYPES = ['string', 'multiline', 'url', 'json', 'yaml'];
|
|
327
324
|
function generatePageDataTypes(state) {
|
|
325
|
+
// 递归生成TypeScript类型属性
|
|
326
|
+
function generateTsTypeProperties(properties) {
|
|
327
|
+
return Object.entries(properties)
|
|
328
|
+
.map(([, prop]) => {
|
|
329
|
+
if (!prop.data)
|
|
330
|
+
return null;
|
|
331
|
+
// 如果key未定义,使用id
|
|
332
|
+
const key = prop.data.key || prop.data.id;
|
|
333
|
+
if (!key)
|
|
334
|
+
return null;
|
|
335
|
+
// 根据属性类型设置TypeScript类型
|
|
336
|
+
let typeStr = 'string';
|
|
337
|
+
if (prop.data.type === 'string' || prop.data.type === 'multiline') {
|
|
338
|
+
typeStr = 'string';
|
|
339
|
+
}
|
|
340
|
+
else if (prop.data.type === 'number') {
|
|
341
|
+
typeStr = 'number';
|
|
342
|
+
}
|
|
343
|
+
else if (prop.data.type === 'url') {
|
|
344
|
+
typeStr = '{ url: string; mediaKitUrl?: string; width?: number; height?: number }';
|
|
345
|
+
}
|
|
346
|
+
else if (prop.data.type === 'json' || prop.data.type === 'yaml') {
|
|
347
|
+
// 处理json类型和嵌套subProperties
|
|
348
|
+
if (prop.data.subProperties && Object.keys(prop.data.subProperties).length > 0) {
|
|
349
|
+
const subProps = generateTsTypeProperties(prop.data.subProperties).filter(Boolean).join('\n ');
|
|
350
|
+
typeStr = `{\n ${subProps}\n }`;
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
typeStr = 'any';
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
typeStr = 'any';
|
|
358
|
+
}
|
|
359
|
+
return ` "${key}"?: ${typeStr};`;
|
|
360
|
+
})
|
|
361
|
+
.filter(Boolean);
|
|
362
|
+
}
|
|
328
363
|
const pageTypeDefinitions = Object.values(state.pages)
|
|
329
364
|
.map((page) => {
|
|
330
365
|
if (!page.isTemplate)
|
|
@@ -338,7 +373,6 @@ function generatePageDataTypes(state) {
|
|
|
338
373
|
// 收集所有 section 的配置信息
|
|
339
374
|
const sectionTypes = page.sectionIds
|
|
340
375
|
.map((sectionId) => {
|
|
341
|
-
var _a, _b, _c, _d;
|
|
342
376
|
const section = page.sections[sectionId];
|
|
343
377
|
if (!section)
|
|
344
378
|
return null;
|
|
@@ -346,24 +380,30 @@ function generatePageDataTypes(state) {
|
|
|
346
380
|
if (!section.isTemplateSection)
|
|
347
381
|
return null;
|
|
348
382
|
if (section.component === 'custom-component') {
|
|
349
|
-
const componentId =
|
|
383
|
+
const componentId = section.config?.componentId;
|
|
350
384
|
if (!componentId)
|
|
351
385
|
return null;
|
|
352
|
-
const component =
|
|
386
|
+
const component = state.components[componentId]?.data || state.resources.components?.[componentId]?.component;
|
|
353
387
|
if (!component)
|
|
354
388
|
return null;
|
|
355
389
|
// 为自定义组件生成属性类型
|
|
356
390
|
const properties = Object.entries(component.properties || {})
|
|
357
391
|
.map(([, prop]) => {
|
|
358
|
-
var _a, _b, _c, _d, _e;
|
|
359
392
|
// check if the property type is allowed
|
|
360
|
-
if (
|
|
393
|
+
if (prop.data?.type && !ALLOWED_PROPERTY_TYPES.includes(prop.data?.type))
|
|
361
394
|
return null;
|
|
362
395
|
// if key is undefined, use id
|
|
363
|
-
const key =
|
|
396
|
+
const key = prop.data?.key || prop.data?.id;
|
|
364
397
|
if (!key)
|
|
365
398
|
return null;
|
|
366
|
-
|
|
399
|
+
// 处理JSON类型属性,如果有subProperties则递归生成类型
|
|
400
|
+
if ((prop.data?.type === 'json' || prop.data?.type === 'yaml') &&
|
|
401
|
+
prop.data?.subProperties &&
|
|
402
|
+
Object.keys(prop.data.subProperties).length > 0) {
|
|
403
|
+
const subProps = generateTsTypeProperties(prop.data.subProperties).filter(Boolean).join('\n ');
|
|
404
|
+
return ` "${key}"?: {\n ${subProps}\n };`;
|
|
405
|
+
}
|
|
406
|
+
return ` "${key}"?: ${getCustomComponentPropertyType(prop.data?.type)};`;
|
|
367
407
|
})
|
|
368
408
|
.filter(Boolean)
|
|
369
409
|
.join('\n');
|
|
@@ -394,13 +434,13 @@ ${sectionTypes}
|
|
|
394
434
|
})
|
|
395
435
|
.filter(Boolean);
|
|
396
436
|
// Generate type definitions string
|
|
397
|
-
const typeDefinitions = pageTypeDefinitions.map((def) => `export ${def
|
|
437
|
+
const typeDefinitions = pageTypeDefinitions.map((def) => `export ${def?.typeDefinition}`).join('\n\n');
|
|
398
438
|
// Generate string literals for each type
|
|
399
439
|
const typeStrings = pageTypeDefinitions
|
|
400
|
-
.map((def) => `export const ${def
|
|
440
|
+
.map((def) => `export const ${def?.typeName}String = \`${def?.typeDefinition}\`;`)
|
|
401
441
|
.join('\n\n');
|
|
402
442
|
// Generate union type
|
|
403
|
-
const pageUnionTypes = pageTypeDefinitions.map((def) => def
|
|
443
|
+
const pageUnionTypes = pageTypeDefinitions.map((def) => def?.typeName).join(' | ');
|
|
404
444
|
return `
|
|
405
445
|
// Page data type definitions
|
|
406
446
|
${typeDefinitions}
|
|
@@ -411,4 +451,210 @@ ${typeStrings}
|
|
|
411
451
|
// Union type of all page data types
|
|
412
452
|
export type PageDataUnion = ${pageUnionTypes || 'never'};`;
|
|
413
453
|
}
|
|
454
|
+
// 为每个页面数据类型生成JSONSchema
|
|
455
|
+
function generatePageDataJsonSchemas(state) {
|
|
456
|
+
// 递归生成JSON Schema属性
|
|
457
|
+
function generateJsonSchemaProperties(properties) {
|
|
458
|
+
const schemaProperties = {};
|
|
459
|
+
Object.entries(properties).forEach(([, prop]) => {
|
|
460
|
+
if (!prop.data)
|
|
461
|
+
return;
|
|
462
|
+
// 如果key未定义,使用id
|
|
463
|
+
const key = prop.data.key || prop.data.id;
|
|
464
|
+
if (!key)
|
|
465
|
+
return;
|
|
466
|
+
// 根据属性类型设置Schema
|
|
467
|
+
if (prop.data.type === 'string' || prop.data.type === 'multiline') {
|
|
468
|
+
schemaProperties[key] = { type: 'string' };
|
|
469
|
+
}
|
|
470
|
+
else if (prop.data.type === 'number') {
|
|
471
|
+
schemaProperties[key] = { type: 'number' };
|
|
472
|
+
}
|
|
473
|
+
else if (prop.data.type === 'url') {
|
|
474
|
+
schemaProperties[key] = {
|
|
475
|
+
type: 'object',
|
|
476
|
+
properties: {
|
|
477
|
+
url: { type: 'string' },
|
|
478
|
+
mediaKitUrl: { type: 'string' },
|
|
479
|
+
width: { type: 'number' },
|
|
480
|
+
height: { type: 'number' },
|
|
481
|
+
},
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
else if (prop.data.type === 'json' || prop.data.type === 'yaml') {
|
|
485
|
+
// 处理json类型和嵌套subProperties
|
|
486
|
+
if (prop.data.subProperties && Object.keys(prop.data.subProperties).length > 0) {
|
|
487
|
+
schemaProperties[key] = {
|
|
488
|
+
type: 'object',
|
|
489
|
+
properties: generateJsonSchemaProperties(prop.data.subProperties),
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
schemaProperties[key] = {};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
schemaProperties[key] = { type: 'string' };
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
return schemaProperties;
|
|
501
|
+
}
|
|
502
|
+
const pageSchemaDefinitions = Object.values(state.pages)
|
|
503
|
+
.map((page) => {
|
|
504
|
+
if (!page.isTemplate)
|
|
505
|
+
return null;
|
|
506
|
+
const typeName = `Page${page.slug
|
|
507
|
+
.replace(/^\//, '')
|
|
508
|
+
.split('/')
|
|
509
|
+
.map((s) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
510
|
+
.join('')
|
|
511
|
+
.replace(/[^a-zA-Z0-9]/g, '')}Data`;
|
|
512
|
+
// 收集所有 section 的配置信息
|
|
513
|
+
const sectionProperties = {};
|
|
514
|
+
page.sectionIds.forEach((sectionId) => {
|
|
515
|
+
const section = page.sections[sectionId];
|
|
516
|
+
if (!section || !section.isTemplateSection)
|
|
517
|
+
return;
|
|
518
|
+
const sectionName = section.name || section.id;
|
|
519
|
+
if (section.component === 'custom-component') {
|
|
520
|
+
const componentId = section.config?.componentId;
|
|
521
|
+
if (!componentId)
|
|
522
|
+
return;
|
|
523
|
+
const component = state.components[componentId]?.data || state.resources.components?.[componentId]?.component;
|
|
524
|
+
if (!component)
|
|
525
|
+
return;
|
|
526
|
+
// 为自定义组件生成属性Schema
|
|
527
|
+
const properties = {};
|
|
528
|
+
Object.entries(component.properties || {}).forEach(([, prop]) => {
|
|
529
|
+
// 检查属性类型是否允许
|
|
530
|
+
if (prop.data?.type && !ALLOWED_PROPERTY_TYPES.includes(prop.data?.type))
|
|
531
|
+
return;
|
|
532
|
+
// 如果key未定义,使用id
|
|
533
|
+
const key = prop.data?.key || prop.data?.id;
|
|
534
|
+
if (!key)
|
|
535
|
+
return;
|
|
536
|
+
// 设置属性的Schema类型
|
|
537
|
+
if (prop.data?.type === 'string' || prop.data?.type === 'multiline') {
|
|
538
|
+
properties[key] = { type: 'string' };
|
|
539
|
+
}
|
|
540
|
+
else if (prop.data?.type === 'url') {
|
|
541
|
+
properties[key] = {
|
|
542
|
+
type: 'object',
|
|
543
|
+
properties: {
|
|
544
|
+
url: { type: 'string' },
|
|
545
|
+
mediaKitUrl: { type: 'string' },
|
|
546
|
+
width: { type: 'number' },
|
|
547
|
+
height: { type: 'number' },
|
|
548
|
+
},
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
else if (prop.data?.type === 'json' || prop.data?.type === 'yaml') {
|
|
552
|
+
// 处理json类型的属性
|
|
553
|
+
if (prop.data?.subProperties && Object.keys(prop.data.subProperties).length > 0) {
|
|
554
|
+
properties[key] = {
|
|
555
|
+
type: 'object',
|
|
556
|
+
properties: generateJsonSchemaProperties(prop.data.subProperties),
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
properties[key] = {};
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
properties[key] = { type: 'string' };
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
if (Object.keys(properties).length > 0) {
|
|
568
|
+
sectionProperties[sectionName] = {
|
|
569
|
+
type: 'object',
|
|
570
|
+
properties,
|
|
571
|
+
description: section.templateDescription,
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
else if (basicComponentSectionTypes[section.component]) {
|
|
576
|
+
// 处理基本组件section类型
|
|
577
|
+
const schemaProperties = {};
|
|
578
|
+
// 将类型字符串转换为JSONSchema格式
|
|
579
|
+
if (section.component === 'iframe') {
|
|
580
|
+
schemaProperties.src = { type: 'string' };
|
|
581
|
+
schemaProperties.title = { type: 'string' };
|
|
582
|
+
schemaProperties.description = { type: 'string' };
|
|
583
|
+
}
|
|
584
|
+
else if (section.component === 'section') {
|
|
585
|
+
schemaProperties.title = { type: 'string' };
|
|
586
|
+
schemaProperties.description = { type: 'string' };
|
|
587
|
+
schemaProperties.image = { type: 'string' };
|
|
588
|
+
schemaProperties.imageMeta = {
|
|
589
|
+
type: 'object',
|
|
590
|
+
properties: {
|
|
591
|
+
naturalWidth: { type: 'number' },
|
|
592
|
+
naturalHeight: { type: 'number' },
|
|
593
|
+
filename: { type: 'string' },
|
|
594
|
+
},
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
else if (section.component === 'section-card-list') {
|
|
598
|
+
schemaProperties.title = { type: 'string' };
|
|
599
|
+
schemaProperties.description = { type: 'string' };
|
|
600
|
+
schemaProperties.list = {
|
|
601
|
+
type: 'array',
|
|
602
|
+
items: {
|
|
603
|
+
type: 'object',
|
|
604
|
+
properties: {
|
|
605
|
+
id: { type: 'string' },
|
|
606
|
+
title: { type: 'string' },
|
|
607
|
+
description: { type: 'string' },
|
|
608
|
+
image: { type: 'string' },
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
else if (section.component === 'toc') {
|
|
614
|
+
schemaProperties.title = { type: 'string' };
|
|
615
|
+
schemaProperties.description = { type: 'string' };
|
|
616
|
+
}
|
|
617
|
+
sectionProperties[sectionName] = {
|
|
618
|
+
type: 'object',
|
|
619
|
+
properties: schemaProperties,
|
|
620
|
+
description: section.templateDescription,
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
// 其他类型的section
|
|
625
|
+
sectionProperties[sectionName] = {
|
|
626
|
+
type: 'object',
|
|
627
|
+
properties: {},
|
|
628
|
+
description: section.templateDescription,
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
// 创建页面的JSONSchema定义
|
|
633
|
+
const schema = {
|
|
634
|
+
type: 'object',
|
|
635
|
+
properties: {
|
|
636
|
+
title: { type: 'string' },
|
|
637
|
+
image: { type: 'string' },
|
|
638
|
+
description: { type: 'string' },
|
|
639
|
+
sectionsData: {
|
|
640
|
+
type: 'object',
|
|
641
|
+
properties: sectionProperties,
|
|
642
|
+
description: '包含页面的所有部分数据',
|
|
643
|
+
},
|
|
644
|
+
},
|
|
645
|
+
};
|
|
646
|
+
return {
|
|
647
|
+
typeName: `${typeName}Schema`,
|
|
648
|
+
schema,
|
|
649
|
+
};
|
|
650
|
+
})
|
|
651
|
+
.filter(Boolean);
|
|
652
|
+
// 生成Schema导出代码
|
|
653
|
+
const schemaExports = pageSchemaDefinitions
|
|
654
|
+
.map((def) => `export const ${def?.typeName} = ${JSON.stringify(def?.schema, null, 2)};`)
|
|
655
|
+
.join('\n\n');
|
|
656
|
+
return `
|
|
657
|
+
// JSONSchema definitions for page data types
|
|
658
|
+
${schemaExports}`;
|
|
659
|
+
}
|
|
414
660
|
exports.default = generateWrapperCode;
|
package/lib/cjs/utils/helper.js
CHANGED
|
@@ -35,15 +35,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
36
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
37
|
};
|
|
38
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
39
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
40
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
41
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
42
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
43
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
44
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
38
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
48
39
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
49
40
|
};
|
|
@@ -98,7 +89,7 @@ function findComponentFiles(options = {}) {
|
|
|
98
89
|
metadata,
|
|
99
90
|
};
|
|
100
91
|
})
|
|
101
|
-
.filter(({ blockName }) => !
|
|
92
|
+
.filter(({ blockName }) => !filter?.length || filter.includes(blockName || ''));
|
|
102
93
|
}
|
|
103
94
|
function getBlockName(entry) {
|
|
104
95
|
// First try to match index.{ts,tsx,html} pattern
|
|
@@ -126,7 +117,7 @@ const isMetadataFile = (filePath) => {
|
|
|
126
117
|
return filePath.endsWith(constants_1.METADATA_FILE_NAME);
|
|
127
118
|
};
|
|
128
119
|
exports.isMetadataFile = isMetadataFile;
|
|
129
|
-
const downloadAsset =
|
|
120
|
+
const downloadAsset = async ({ asset, savePath, componentDid, }) => {
|
|
130
121
|
if (!componentDid || !exports.isDev || !asset || !savePath) {
|
|
131
122
|
throw new Error('Invalid params');
|
|
132
123
|
}
|
|
@@ -136,9 +127,9 @@ const downloadAsset = (_a) => __awaiter(void 0, [_a], void 0, function* ({ asset
|
|
|
136
127
|
}
|
|
137
128
|
const fileName = (0, path_1.basename)(asset);
|
|
138
129
|
// Ensure target directory exists
|
|
139
|
-
|
|
130
|
+
await (0, promises_1.mkdir)(path_1.default.dirname(savePath), { recursive: true });
|
|
140
131
|
// download asset from pages-kit's /uploads
|
|
141
|
-
const res =
|
|
132
|
+
const res = await (0, component_1.call)({
|
|
142
133
|
name: process.env.BLOCKLET_COMPONENT_DID,
|
|
143
134
|
path: (0, ufo_1.joinURL)('/uploads', fileName),
|
|
144
135
|
responseType: 'stream',
|
|
@@ -146,12 +137,12 @@ const downloadAsset = (_a) => __awaiter(void 0, [_a], void 0, function* ({ asset
|
|
|
146
137
|
});
|
|
147
138
|
if (res.status >= 200 && res.status < 400) {
|
|
148
139
|
const file = fs_1.default.createWriteStream(savePath);
|
|
149
|
-
|
|
140
|
+
await (0, promises_2.pipeline)(res.data, file);
|
|
150
141
|
}
|
|
151
142
|
else {
|
|
152
143
|
throw new Error(`download asset failed ${res.status}`);
|
|
153
144
|
}
|
|
154
|
-
}
|
|
145
|
+
};
|
|
155
146
|
exports.downloadAsset = downloadAsset;
|
|
156
147
|
const getPreviewImageRelativePath = (name) => {
|
|
157
148
|
return path_1.default.join(constants_1.PREVIEW_IMAGE_DIR, name);
|
|
@@ -175,7 +166,7 @@ function initializeMetadata(tempFilePath) {
|
|
|
175
166
|
try {
|
|
176
167
|
metadata = JSON.parse(content);
|
|
177
168
|
}
|
|
178
|
-
catch
|
|
169
|
+
catch {
|
|
179
170
|
// If parsing fails, use empty object
|
|
180
171
|
}
|
|
181
172
|
}
|
|
@@ -208,7 +199,6 @@ function getBlockStudioInfo() {
|
|
|
208
199
|
}
|
|
209
200
|
exports.isPagesKitBlockStudio = process.env.BLOCKLET_COMPONENT_DID === constants_1.PAGES_KIT_BLOCK_STUDIO_DID;
|
|
210
201
|
const getBlockCode = (filePath) => {
|
|
211
|
-
var _a;
|
|
212
202
|
// Check path safety first
|
|
213
203
|
if (!(0, exports.isPathSafe)(filePath)) {
|
|
214
204
|
throw new Error('Invalid file path: path traversal detected');
|
|
@@ -219,7 +209,7 @@ const getBlockCode = (filePath) => {
|
|
|
219
209
|
if (!files.length) {
|
|
220
210
|
throw new Error(`No code file found for block: ${blockName}`);
|
|
221
211
|
}
|
|
222
|
-
const codeFile =
|
|
212
|
+
const codeFile = files[0]?.fullPath;
|
|
223
213
|
if (!codeFile) {
|
|
224
214
|
throw new Error(`No code file found for block: ${blockName}`);
|
|
225
215
|
}
|
|
@@ -230,7 +220,7 @@ const safeParse = (text) => {
|
|
|
230
220
|
try {
|
|
231
221
|
return JSON.parse(text);
|
|
232
222
|
}
|
|
233
|
-
catch
|
|
223
|
+
catch {
|
|
234
224
|
return null;
|
|
235
225
|
}
|
|
236
226
|
};
|