@blocklet/pages-kit-block-studio 0.4.133 → 0.4.134

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.
@@ -37,9 +37,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.initBlockStudioRouter = void 0;
40
- /* eslint-disable */
40
+ // @ts-nocheck
41
41
  const express_1 = require("express");
42
42
  const fs_1 = __importDefault(require("fs"));
43
+ const glob_1 = require("glob");
43
44
  const isEqual_1 = __importDefault(require("lodash/isEqual"));
44
45
  const keyBy_1 = __importDefault(require("lodash/keyBy"));
45
46
  const set_1 = __importDefault(require("lodash/set"));
@@ -126,7 +127,10 @@ exports.initBlockStudioRouter.post('/', async (req, res) => {
126
127
  if (!fs_1.default.existsSync(dir)) {
127
128
  throw new Error('Directory not found');
128
129
  }
129
- const currentMetadata = (0, helper_1.initializeMetadata)(filePath);
130
+ const currentMetadata = (0, helper_1.initializeMetadata)(filePath, true);
131
+ if (!currentMetadata) {
132
+ return res.status(404).json({ error: 'Metadata file not found' });
133
+ }
130
134
  const mergedContent = { ...currentMetadata, ...content };
131
135
  if ((0, isEqual_1.default)(currentMetadata, mergedContent)) {
132
136
  return res.json({ success: true, content: mergedContent, message: 'No changes' });
@@ -161,7 +165,25 @@ exports.initBlockStudioRouter.post('/create', async (req, res) => {
161
165
  }
162
166
  try {
163
167
  const pattern = (0, helper_1.getBlockEntryFilesPattern)();
164
- const baseDir = path_1.default.dirname(pattern.replace(/\*\*?/g, ''));
168
+ let baseDir = path_1.default.dirname(pattern.replace(/\*\*?/g, ''));
169
+ // 使用glob快速查找包含@metadata.json的目录
170
+ try {
171
+ // 从baseDir开始向上查找所有包含@metadata.json的目录
172
+ const metadataFiles = (0, glob_1.globSync)(`**/${constants_1.METADATA_FILE_NAME}`, {
173
+ cwd: baseDir,
174
+ absolute: true,
175
+ });
176
+ // 按照目录层级深度排序,找到最近的目录
177
+ if (metadataFiles.length > 0) {
178
+ // 按路径长度排序,最短的路径通常是最接近baseDir的
179
+ metadataFiles.sort((a, b) => a.length - b.length);
180
+ const closestMetadataDir = path_1.default.dirname(metadataFiles[0]);
181
+ baseDir = path_1.default.dirname(closestMetadataDir);
182
+ }
183
+ }
184
+ catch (error) {
185
+ console.warn('Error searching for metadata files:', error);
186
+ }
165
187
  const blockDir = path_1.default.join(baseDir, name);
166
188
  const metadataPath = path_1.default.join(blockDir, constants_1.METADATA_FILE_NAME);
167
189
  const indexPath = path_1.default.join(blockDir, 'index.tsx');
@@ -270,7 +292,7 @@ exports.initBlockStudioRouter.post('/properties-to-interface', async (req, res)
270
292
  fs_1.default.writeFileSync(componentPath, updatedCode);
271
293
  return res.json({
272
294
  success: true,
273
- message: 'TypeScript接口已成功从metadata生成并写入文件',
295
+ message: 'TypeScript interface generated successfully!',
274
296
  });
275
297
  }
276
298
  // 否则,只返回生成的接口内容,不写入文件
@@ -336,7 +358,7 @@ exports.initBlockStudioRouter.post('/interface-to-properties', async (req, res)
336
358
  return res.json({
337
359
  success: true,
338
360
  metadata: newMetadata,
339
- message: 'Metadata 完全更新成功',
361
+ message: 'Metadata updated successfully!',
340
362
  });
341
363
  }
342
364
  // 否则,只返回差异信息,不写入文件
@@ -40,8 +40,10 @@ exports.initUploaderRouter = void 0;
40
40
  const config_1 = __importDefault(require("@blocklet/sdk/lib/config"));
41
41
  const uploader_server_1 = require("@blocklet/uploader-server");
42
42
  const express_1 = __importStar(require("express"));
43
+ const glob_1 = require("glob");
43
44
  const path_1 = require("path");
44
45
  const constants_1 = require("../constants");
46
+ const helper_1 = require("../utils/helper");
45
47
  // init uploader router
46
48
  exports.initUploaderRouter = (0, express_1.Router)();
47
49
  const staticResourceMiddleware = (0, uploader_server_1.initStaticResourceMiddleware)({
@@ -89,7 +91,16 @@ const dynamicResourceMiddleware = (0, uploader_server_1.initDynamicResourceMiddl
89
91
  });
90
92
  exports.initUploaderRouter.use('/uploads', (0, uploader_server_1.initProxyToMediaKitUploadsMiddleware)({
91
93
  express: express_1.default,
92
- }), staticResourceMiddleware, (_req, res) => {
94
+ }), staticResourceMiddleware, (req, res) => {
95
+ // if is component studio, should getting from `@preview-images` folder, only in dev mode
96
+ if (helper_1.isDev && config_1.default.env.componentDid === constants_1.PAGES_KIT_BLOCK_STUDIO_DID) {
97
+ const globPath = (0, path_1.join)(process.cwd(), (0, path_1.dirname)((0, helper_1.getBlockEntryFilesPattern)()), (0, helper_1.getPreviewImageRelativePath)((0, path_1.basename)(req.url)));
98
+ const files = (0, glob_1.globSync)(globPath);
99
+ if (files?.[0]) {
100
+ res.sendFile(files[0]);
101
+ return;
102
+ }
103
+ }
93
104
  res.status(404).send('404 NOT FOUND').end();
94
105
  });
95
106
  exports.initUploaderRouter.use('/chunks', dynamicResourceMiddleware, staticResourceMiddleware, (_req, res) => {
@@ -161,13 +161,12 @@ function Layout({ loadState, loadedData }) {
161
161
  const location = (0, react_router_dom_1.useLocation)();
162
162
  const navigate = (0, react_router_dom_1.useNavigate)();
163
163
  const staticData = (0, client_1.useStaticData)();
164
- const { routes, firstRoute, currentPage } = (0, react_1.useMemo)(() => {
164
+ const { routes, currentPage } = (0, react_1.useMemo)(() => {
165
165
  const routes = Object.keys(staticData)
166
166
  .sort((a, b) => a.localeCompare(b))
167
167
  .filter((route) => staticData[route]?.main?.isDeleted !== true);
168
168
  return {
169
169
  routes,
170
- firstRoute: routes.find((route) => route !== '404' && route !== '*'),
171
170
  currentPage: {
172
171
  ...staticData[location.pathname]?.main,
173
172
  pageId: location.pathname,
@@ -663,12 +662,6 @@ function Layout({ loadState, loadedData }) {
663
662
  getStaticData,
664
663
  state.draggingSplitPane,
665
664
  ]);
666
- // add auto redirect to first route
667
- if (loadState.type === '404' &&
668
- !routes.includes(location.pathname) &&
669
- !location.search.includes('no-redirect=true')) {
670
- return (0, jsx_runtime_1.jsx)(react_router_dom_1.Navigate, { to: `${firstRoute ?? '/'}`, replace: true });
671
- }
672
665
  if (isInsideIframe) {
673
666
  return middlePanelContent;
674
667
  }
@@ -117,6 +117,16 @@ function initBlockStudioPlugins(options) {
117
117
  const entryFilesPattern = options?.entryFilesPattern || (0, helper_1.getBlockEntryFilesPattern)();
118
118
  const transpileBuiltinModule = options?.transpileBuiltinModule ?? true;
119
119
  const ignoreSplitEditComponent = options?.ignoreSplitEditComponent ?? false;
120
+ const watchFilesDir = options?.watchFilesDir || (0, helper_1.getWatchFilesDir)() || workingDir;
121
+ // default fallback to __dirname if _theme.tsx not exists
122
+ let pagesDir = __dirname.replace('cjs', 'esm');
123
+ // 如果存在 .component-studio-runtime 目录,则使用它
124
+ if ((0, fs_1.existsSync)(path.join(workingDir, '.component-studio-runtime', '_theme.tsx'))) {
125
+ pagesDir = path.join(workingDir, '.component-studio-runtime');
126
+ }
127
+ else if ((0, fs_1.existsSync)(path.join(workingDir, '_theme.tsx'))) {
128
+ pagesDir = workingDir;
129
+ }
120
130
  // 处理 blockExternals 参数
121
131
  let externalMappings = defaultBlockExternals;
122
132
  if (typeof options?.blockExternals === 'function') {
@@ -128,10 +138,9 @@ function initBlockStudioPlugins(options) {
128
138
  externalMappings = options.blockExternals;
129
139
  }
130
140
  (0, helper_1.setBlockEntryFilesPattern)(entryFilesPattern);
131
- // fallback to __dirname if _theme.tsx not exists
132
- const pagesDir = (0, fs_1.existsSync)(path.join(workingDir, '_theme.tsx')) ? workingDir : __dirname.replace('cjs', 'esm');
133
141
  helper_1.logger.log('initBlockStudioPlugins options: ', {
134
142
  cwd: workingDir,
143
+ watchFilesDir,
135
144
  entryFilesPattern: (0, helper_1.getBlockEntryFilesPattern)(),
136
145
  pagesDir,
137
146
  blockExternals: externalMappings, // 添加日志输出
@@ -154,7 +163,7 @@ function initBlockStudioPlugins(options) {
154
163
  const filterModules = process.argv.includes('--filter')
155
164
  ? process.argv[process.argv.indexOf('--filter') + 1]?.split(',')
156
165
  : null;
157
- const entryList = (0, helper_1.findComponentFiles)({ cwd: workingDir })
166
+ const entryList = (0, helper_1.findComponentFiles)({ cwd: watchFilesDir })
158
167
  .map((entry) => {
159
168
  const { blockName } = entry;
160
169
  const { isHtml } = entry;
@@ -162,7 +171,7 @@ function initBlockStudioPlugins(options) {
162
171
  if (isHtml) {
163
172
  return [blockName, `${vite_plugin_html_transform_1.VIRTUAL_MODULE_ID}?dir=${path.dirname(file)}`];
164
173
  }
165
- return [blockName, path.resolve(workingDir, file)];
174
+ return [blockName, path.resolve(watchFilesDir, file)];
166
175
  })
167
176
  .filter(Boolean)
168
177
  .filter(([blockName]) => !filterModules || filterModules.includes(blockName || ''));
@@ -197,7 +206,7 @@ function initBlockStudioPlugins(options) {
197
206
  enforce: 'pre',
198
207
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
199
208
  async config(_config) {
200
- const name = await Promise.resolve(`${`${workingDir}/package.json`}`).then(s => __importStar(require(s))).then((res) => res.name).catch(() => 'MyLib');
209
+ const name = await Promise.resolve(`${`${watchFilesDir}/package.json`}`).then(s => __importStar(require(s))).then((res) => res.name).catch(() => 'MyLib');
201
210
  return {
202
211
  mode: 'production',
203
212
  resolve: {
@@ -278,7 +287,7 @@ function initBlockStudioPlugins(options) {
278
287
  pagesDir,
279
288
  pageStrategy: new vite_plugin_react_pages_1.DefaultPageStrategy({
280
289
  extraFindPages: async (_pagesDir, helpers) => {
281
- helpers.watchFiles(workingDir, (0, helper_1.getBlockEntryFilesPattern)(), async function fileHandler(file, api) {
290
+ helpers.watchFiles(watchFilesDir, (0, helper_1.getBlockEntryFilesPattern)(), async function fileHandler(file, api) {
282
291
  const { relative, path: filePath } = file;
283
292
  const isHtml = false && relative.endsWith('.html');
284
293
  const blockName = (0, helper_1.getBlockName)(relative);