@knotx/cli 0.2.11 → 0.2.12

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/dist/index.cjs CHANGED
@@ -10,15 +10,31 @@ const commander = require('commander');
10
10
  const fs = require('fs-extra');
11
11
  const inquirer = require('inquirer');
12
12
  const ora = require('ora');
13
+ const ts = require('typescript');
14
+ const TJS = require('typescript-json-schema');
13
15
 
14
16
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
15
17
 
18
+ function _interopNamespaceCompat(e) {
19
+ if (e && typeof e === 'object' && 'default' in e) return e;
20
+ const n = Object.create(null);
21
+ if (e) {
22
+ for (const k in e) {
23
+ n[k] = e[k];
24
+ }
25
+ }
26
+ n.default = e;
27
+ return n;
28
+ }
29
+
16
30
  const path__default = /*#__PURE__*/_interopDefaultCompat(path);
17
31
  const process__default = /*#__PURE__*/_interopDefaultCompat(process);
18
32
  const chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
19
33
  const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
20
34
  const inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
21
35
  const ora__default = /*#__PURE__*/_interopDefaultCompat(ora);
36
+ const ts__default = /*#__PURE__*/_interopDefaultCompat(ts);
37
+ const TJS__namespace = /*#__PURE__*/_interopNamespaceCompat(TJS);
22
38
 
23
39
  var __defProp = Object.defineProperty;
24
40
  var __defProps = Object.defineProperties;
@@ -165,6 +181,419 @@ program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u76
165
181
  console.error(chalk__default.red(error));
166
182
  }
167
183
  }));
184
+ program.command("generate-jsonschema").aliases(["gen-schema", "schema"]).description("\u6839\u636E PluginTools \u7C7B\u578B\u58F0\u660E\u751F\u6210 JSON Schema \u5E76\u66F4\u65B0 @tool \u88C5\u9970\u5668").argument("<file>", "TypeScript \u6587\u4EF6\u8DEF\u5F84").option("-d, --debug", "\u8F93\u51FA\u8BE6\u7EC6\u7684\u8C03\u8BD5\u4FE1\u606F", false).action((file, options) => __async(undefined, null, function* () {
185
+ const spinner = ora__default("\u{1F50D} \u6B63\u5728\u751F\u6210 JSON Schema...").start();
186
+ const debugLog = (message, ...args) => {
187
+ if (options.debug) {
188
+ console.log(message, ...args);
189
+ }
190
+ };
191
+ try {
192
+ let findPluginToolsInterface = function(node) {
193
+ if (ts__default.isModuleDeclaration(node) && node.name) {
194
+ const moduleName = ts__default.isStringLiteral(node.name) ? node.name.text : node.name.getText();
195
+ if (moduleName.includes("@knotx/core")) {
196
+ debugLog("\u627E\u5230\u6A21\u5757\u58F0\u660E:", moduleName);
197
+ if (node.body && ts__default.isModuleBlock(node.body)) {
198
+ node.body.statements.forEach((statement) => {
199
+ if (ts__default.isInterfaceDeclaration(statement) && statement.name && statement.name.text === "PluginTools") {
200
+ pluginToolsInterface = statement;
201
+ debugLog("\u627E\u5230 PluginTools \u63A5\u53E3:", statement.name.text, "\uFF0C\u5305\u542B", statement.members.length, "\u4E2A\u6210\u5458");
202
+ statement.members.forEach((member) => {
203
+ if (ts__default.isPropertySignature(member) && member.name) {
204
+ const memberName = ts__default.isIdentifier(member.name) ? member.name.text : member.name.getText();
205
+ debugLog("- \u6210\u5458:", memberName);
206
+ if (!pluginNames.includes(memberName)) {
207
+ pluginNames.push(memberName);
208
+ }
209
+ }
210
+ });
211
+ }
212
+ });
213
+ }
214
+ }
215
+ }
216
+ ts__default.forEachChild(node, findPluginToolsInterface);
217
+ }, findPluginClasses = function(node) {
218
+ if (ts__default.isClassDeclaration(node) && node.name) {
219
+ const className = node.name.text;
220
+ debugLog(`\u68C0\u67E5\u7C7B: ${className}`);
221
+ let isPlugin = false;
222
+ let pluginGenericType = "";
223
+ if (node.heritageClauses) {
224
+ for (const clause of node.heritageClauses) {
225
+ for (const type of clause.types) {
226
+ const expr = type.expression.getText(sourceFile);
227
+ if (expr === "BasePlugin") {
228
+ isPlugin = true;
229
+ if (type.typeArguments && type.typeArguments.length > 0) {
230
+ pluginGenericType = type.typeArguments[0].getText(sourceFile);
231
+ pluginGenericType = pluginGenericType.replace(/['"]/g, "");
232
+ debugLog(` \u63D2\u4EF6\u6CDB\u578B\u7C7B\u578B: ${pluginGenericType}`);
233
+ }
234
+ break;
235
+ }
236
+ }
237
+ }
238
+ }
239
+ let pluginName;
240
+ const members = [];
241
+ if (isPlugin) {
242
+ debugLog(` \u662FBasePlugin\u7684\u5B50\u7C7B`);
243
+ if (node.members) {
244
+ node.members.forEach((member) => {
245
+ if (ts__default.isPropertyDeclaration(member) && member.name && ts__default.isIdentifier(member.name) && member.name.text === "name" && member.initializer) {
246
+ const nameText = member.initializer.getText(sourceFile);
247
+ debugLog(` \u627E\u5230name\u5C5E\u6027: ${nameText}`);
248
+ const cleanNameText = nameText.replace(/['"]|as\s+const/g, "").trim();
249
+ debugLog(` \u6E05\u7406\u540E\u7684name: ${cleanNameText}`);
250
+ if (pluginNames.includes(cleanNameText)) {
251
+ pluginName = cleanNameText;
252
+ debugLog(` \u5339\u914D\u5230\u63D2\u4EF6\u540D\u79F0: ${cleanNameText}`);
253
+ }
254
+ }
255
+ const memberName = member.name ? ts__default.isIdentifier(member.name) ? member.name.text : member.name.getText(sourceFile) : "\u672A\u547D\u540D\u6210\u5458";
256
+ debugLog(` \u68C0\u67E5\u6210\u5458: ${memberName}`);
257
+ let hasToolDecorator = false;
258
+ let toolDecoratorText;
259
+ try {
260
+ if (typeof ts__default.getDecorators === "function") {
261
+ const decorators = ts__default.getDecorators(member);
262
+ if (decorators && decorators.length > 0) {
263
+ debugLog(` \u4F7F\u7528getDecorators\u65B9\u6CD5\u627E\u5230\u88C5\u9970\u5668: ${decorators.length}\u4E2A`);
264
+ for (const decorator of decorators) {
265
+ const decoratorText = decorator.getText(sourceFile);
266
+ debugLog(` \u88C5\u9970\u5668: ${decoratorText}`);
267
+ if (decoratorText.startsWith("@tool")) {
268
+ hasToolDecorator = true;
269
+ toolDecoratorText = decoratorText;
270
+ debugLog(` \u627E\u5230tool\u88C5\u9970\u5668: ${decoratorText}`);
271
+ break;
272
+ }
273
+ }
274
+ } else {
275
+ debugLog(` \u6CA1\u6709\u627E\u5230\u88C5\u9970\u5668(getDecorators)`);
276
+ }
277
+ } else {
278
+ debugLog(` ts.getDecorators\u65B9\u6CD5\u4E0D\u53EF\u7528`);
279
+ }
280
+ } catch (err) {
281
+ debugLog(` \u83B7\u53D6\u88C5\u9970\u5668\u65F6\u51FA\u9519:`, err);
282
+ }
283
+ members.push({
284
+ name: memberName,
285
+ hasToolDecorator,
286
+ toolDecoratorText,
287
+ node: member
288
+ });
289
+ });
290
+ }
291
+ if (pluginName) {
292
+ debugLog(`
293
+ \u627E\u5230\u63D2\u4EF6\u7C7B: ${className}, \u63D2\u4EF6\u540D\u79F0: ${pluginName}`);
294
+ const membersWithDecorator = members.filter((m) => m.hasToolDecorator);
295
+ if (membersWithDecorator.length > 0) {
296
+ debugLog(`\u8BE5\u63D2\u4EF6\u6709 ${membersWithDecorator.length} \u4E2A\u6210\u5458\u4F7F\u7528\u4E86 tool \u88C5\u9970\u5668:`);
297
+ membersWithDecorator.forEach((member) => {
298
+ debugLog(`- ${member.name}: ${member.toolDecoratorText}`);
299
+ });
300
+ } else {
301
+ debugLog("\u8BE5\u63D2\u4EF6\u6CA1\u6709\u6210\u5458\u4F7F\u7528 tool \u88C5\u9970\u5668");
302
+ }
303
+ pluginClasses.push({
304
+ className,
305
+ name: pluginName,
306
+ members
307
+ });
308
+ } else if (pluginGenericType) {
309
+ debugLog(`
310
+ \u627E\u5230\u6F5C\u5728\u63D2\u4EF6\u7C7B: ${className}, \u6CDB\u578B\u7C7B\u578B: ${pluginGenericType}`);
311
+ const potentialPluginName = pluginGenericType;
312
+ if (pluginNames.includes(potentialPluginName)) {
313
+ debugLog(`\u6839\u636E\u6CDB\u578B\u7C7B\u578B\u63A8\u65AD\u63D2\u4EF6\u540D\u79F0: ${potentialPluginName}`);
314
+ const membersWithDecorator = members.filter((m) => m.hasToolDecorator);
315
+ if (membersWithDecorator.length > 0) {
316
+ debugLog(`\u8BE5\u63D2\u4EF6\u6709 ${membersWithDecorator.length} \u4E2A\u6210\u5458\u4F7F\u7528\u4E86 tool \u88C5\u9970\u5668:`);
317
+ membersWithDecorator.forEach((member) => {
318
+ debugLog(`- ${member.name}: ${member.toolDecoratorText}`);
319
+ });
320
+ } else {
321
+ debugLog("\u8BE5\u63D2\u4EF6\u6CA1\u6709\u6210\u5458\u4F7F\u7528 tool \u88C5\u9970\u5668");
322
+ }
323
+ pluginClasses.push({
324
+ className,
325
+ name: potentialPluginName,
326
+ members
327
+ });
328
+ } else {
329
+ debugLog(`\u6CDB\u578B\u7C7B\u578B ${potentialPluginName} \u4E0D\u5339\u914D\u4EFB\u4F55\u5DF2\u77E5\u63D2\u4EF6\u540D\u79F0`);
330
+ }
331
+ }
332
+ }
333
+ }
334
+ ts__default.forEachChild(node, findPluginClasses);
335
+ };
336
+ const program2 = TJS__namespace.getProgramFromFiles([file], {
337
+ strictNullChecks: true
338
+ });
339
+ const sourceFile = program2.getSourceFile(file);
340
+ if (!sourceFile) {
341
+ throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u6E90\u6587\u4EF6");
342
+ }
343
+ let sourceCode = yield fs__default.readFile(file, "utf-8");
344
+ debugLog("\u5F00\u59CB\u67E5\u627E PluginTools \u63A5\u53E3...");
345
+ let pluginToolsInterface;
346
+ const pluginNames = [];
347
+ sourceFile.forEachChild(findPluginToolsInterface);
348
+ if (!pluginToolsInterface) {
349
+ debugLog("\u672A\u627E\u5230 PluginTools \u63A5\u53E3");
350
+ } else {
351
+ debugLog(`
352
+ \u627E\u5230\u7684\u63D2\u4EF6\u540D\u79F0:`, pluginNames);
353
+ if (pluginNames.length === 0) {
354
+ debugLog("\u8B66\u544A: \u672A\u627E\u5230\u4EFB\u4F55\u63D2\u4EF6\u540D\u79F0\uFF0C\u8BF7\u786E\u8BA4 PluginTools \u63A5\u53E3\u6269\u5C55\u662F\u5426\u6B63\u786E");
355
+ }
356
+ }
357
+ const pluginClasses = [];
358
+ debugLog("\n\u5F00\u59CB\u67E5\u627E\u63D2\u4EF6\u7C7B...");
359
+ sourceFile.forEachChild(findPluginClasses);
360
+ if (pluginClasses.length === 0) {
361
+ debugLog("\u672A\u627E\u5230\u5BF9\u5E94\u7684\u63D2\u4EF6\u7C7B");
362
+ }
363
+ if (pluginClasses.length > 0) {
364
+ debugLog("\n\u5F00\u59CB\u751F\u6210 JSON Schema \u5E76\u66F4\u65B0 tool \u88C5\u9970\u5668...");
365
+ if (pluginToolsInterface) {
366
+ debugLog("\u63D0\u53D6 PluginTools \u63A5\u53E3\u5B9A\u4E49...");
367
+ const tempTypesDir = path__default.join(path__default.dirname(file), ".temp_types");
368
+ const tempTypesFile = path__default.join(tempTypesDir, "plugin-tools.d.ts");
369
+ try {
370
+ yield fs__default.ensureDir(tempTypesDir);
371
+ let interfaceContent = "/**\n * \u81EA\u52A8\u751F\u6210\u7684\u7C7B\u578B\u5B9A\u4E49\u6587\u4EF6\n */\n\n";
372
+ const paramTypeDefs = [];
373
+ interfaceContent += "export interface PluginTools {\n";
374
+ for (const member of pluginToolsInterface.members) {
375
+ if (ts__default.isPropertySignature(member)) {
376
+ const memberText = member.getText(sourceFile);
377
+ interfaceContent += ` ${memberText}
378
+ `;
379
+ if (member.name) {
380
+ const pluginName = ts__default.isIdentifier(member.name) ? member.name.text : member.name.getText(sourceFile);
381
+ if (member.type && ts__default.isTypeLiteralNode(member.type)) {
382
+ for (const pluginMember of member.type.members) {
383
+ if (ts__default.isPropertySignature(pluginMember) && pluginMember.name) {
384
+ const methodName = ts__default.isIdentifier(pluginMember.name) ? pluginMember.name.text : pluginMember.name.getText(sourceFile);
385
+ if (pluginMember.type && ts__default.isFunctionTypeNode(pluginMember.type) && pluginMember.type.parameters.length > 0 && pluginMember.type.parameters[0].type) {
386
+ const paramTypeText = pluginMember.type.parameters[0].type.getText(sourceFile);
387
+ const paramTypeDef = `// \u53C2\u6570\u7C7B\u578B: ${pluginName}.${methodName}
388
+ export type ${pluginName}_${methodName}_ParamType = ${paramTypeText};
389
+ `;
390
+ paramTypeDefs.push(paramTypeDef);
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ interfaceContent += "}\n\n";
399
+ interfaceContent += paramTypeDefs.join("\n");
400
+ debugLog(`\u63D0\u53D6\u7684\u63A5\u53E3\u5B9A\u4E49:
401
+ ${interfaceContent}`);
402
+ yield fs__default.writeFile(tempTypesFile, interfaceContent);
403
+ debugLog(`\u63A5\u53E3\u5B9A\u4E49\u5DF2\u5199\u5165\u4E34\u65F6\u6587\u4EF6: ${tempTypesFile}`);
404
+ const tempProgram = TJS__namespace.getProgramFromFiles([tempTypesFile], {
405
+ strictNullChecks: true,
406
+ lib: ["ESNext"]
407
+ });
408
+ const generator = TJS__namespace.buildGenerator(tempProgram, {
409
+ required: true,
410
+ noExtraProps: true,
411
+ skipLibCheck: true
412
+ });
413
+ if (!generator) {
414
+ throw new Error("\u65E0\u6CD5\u521B\u5EFA JSON Schema \u751F\u6210\u5668");
415
+ }
416
+ const allSymbols = generator.getUserSymbols();
417
+ debugLog("\u53EF\u7528\u7684\u7C7B\u578B\u7B26\u53F7:", allSymbols);
418
+ let updatedDecoratorsCount = 0;
419
+ for (const pluginClass of pluginClasses) {
420
+ debugLog(`
421
+ \u5904\u7406\u63D2\u4EF6: ${pluginClass.className} (${pluginClass.name})`);
422
+ const membersWithDecorator = pluginClass.members.filter((m) => m.hasToolDecorator);
423
+ if (membersWithDecorator.length > 0) {
424
+ debugLog(`\u5904\u7406 ${membersWithDecorator.length} \u4E2A\u5E26 tool \u88C5\u9970\u5668\u7684\u6210\u5458`);
425
+ for (const member of membersWithDecorator) {
426
+ const memberName = member.name;
427
+ debugLog(`\u5904\u7406\u6210\u5458: ${memberName}`);
428
+ try {
429
+ const typeName = `${pluginClass.name}_${memberName}_ParamType`;
430
+ debugLog(`\u67E5\u627E\u7C7B\u578B: ${typeName}`);
431
+ if (allSymbols.includes(typeName)) {
432
+ const schema = generator.getSchemaForSymbol(typeName);
433
+ if (schema) {
434
+ debugLog(`\u6210\u529F\u751F\u6210 JSON Schema:`, `${JSON.stringify(schema).substring(0, 50)}...`);
435
+ if (member.toolDecoratorText) {
436
+ const oldDecoratorText = member.toolDecoratorText;
437
+ const hasSecondParam = /^@tool\s*\(\s*(['"]).*\1\s*,/.test(oldDecoratorText);
438
+ let newDecoratorText;
439
+ if (hasSecondParam) {
440
+ newDecoratorText = oldDecoratorText.replace(
441
+ /^(@tool\s*\(\s*(['"]).*\2\s*),\s*(?:\S.*)?\)/,
442
+ `$1, ${JSON.stringify(schema, null, 2)})`
443
+ );
444
+ } else {
445
+ newDecoratorText = oldDecoratorText.replace(
446
+ /^(@tool\s*\(\s*(['"]).*\2\s*)\)/,
447
+ `$1, ${JSON.stringify(schema, null, 2)})`
448
+ );
449
+ }
450
+ debugLog(`\u66F4\u65B0 tool \u88C5\u9970\u5668:`);
451
+ debugLog(` \u65E7: ${oldDecoratorText}`);
452
+ debugLog(` \u65B0: ${newDecoratorText.substring(0, 50)}...`);
453
+ sourceCode = sourceCode.replace(oldDecoratorText, newDecoratorText);
454
+ updatedDecoratorsCount++;
455
+ }
456
+ } else {
457
+ debugLog(`\u8B66\u544A: \u4E3A ${typeName} \u751F\u6210Schema\u5931\u8D25\uFF0C\u4F46\u7C7B\u578B\u5E94\u8BE5\u5B58\u5728`);
458
+ throw new Error(`\u65E0\u6CD5\u4E3A\u5B58\u5728\u7684\u7C7B\u578B ${typeName} \u751F\u6210Schema`);
459
+ }
460
+ } else {
461
+ debugLog(`\u672A\u627E\u5230\u547D\u540D\u7C7B\u578B ${typeName}\uFF0C\u5C1D\u8BD5\u5176\u4ED6\u65B9\u6CD5...`);
462
+ throw new Error(`\u7C7B\u578B ${typeName} \u4E0D\u5728\u53EF\u7528\u7B26\u53F7\u5217\u8868\u4E2D`);
463
+ }
464
+ } catch (error) {
465
+ debugLog(`\u5904\u7406\u6210\u5458 ${memberName} \u65F6\u51FA\u9519:`, error);
466
+ debugLog(`\u5C1D\u8BD5\u5907\u7528\u65B9\u6CD5...`);
467
+ try {
468
+ const pluginProp = pluginToolsInterface.members.find((member2) => {
469
+ if (ts__default.isPropertySignature(member2) && member2.name) {
470
+ const propName = ts__default.isIdentifier(member2.name) ? member2.name.text : member2.name.getText(sourceFile);
471
+ return propName === pluginClass.name;
472
+ }
473
+ return false;
474
+ });
475
+ if (pluginProp && ts__default.isPropertySignature(pluginProp) && pluginProp.type) {
476
+ if (ts__default.isTypeLiteralNode(pluginProp.type)) {
477
+ const methodProp = pluginProp.type.members.find((m) => {
478
+ if (ts__default.isPropertySignature(m) && m.name) {
479
+ const methodName = ts__default.isIdentifier(m.name) ? m.name.text : m.name.getText(sourceFile);
480
+ return methodName === memberName;
481
+ }
482
+ return false;
483
+ });
484
+ if (methodProp && ts__default.isPropertySignature(methodProp) && methodProp.type) {
485
+ if (ts__default.isFunctionTypeNode(methodProp.type) && methodProp.type.parameters.length > 0 && methodProp.type.parameters[0].type) {
486
+ const paramTypeText = methodProp.type.parameters[0].type.getText(sourceFile);
487
+ debugLog(`\u627E\u5230\u53C2\u6570\u7C7B\u578B: ${paramTypeText}`);
488
+ let basicSchema = { type: "object" };
489
+ if (paramTypeText === "string") {
490
+ basicSchema = { type: "string" };
491
+ } else if (paramTypeText === "number") {
492
+ basicSchema = { type: "number" };
493
+ } else if (paramTypeText === "boolean") {
494
+ basicSchema = { type: "boolean" };
495
+ } else if (paramTypeText.startsWith("{") && paramTypeText.endsWith("}")) {
496
+ const content = paramTypeText.slice(1, -1).trim();
497
+ const properties = {};
498
+ const required = [];
499
+ const matches = content.match(/(\w+)(\?)?:\s*(string|number|boolean|\w+)/g) || [];
500
+ matches.forEach((propMatch) => {
501
+ const propParts = /(\w+)(\?)?:\s*(string|number|boolean|\w+)/.exec(propMatch);
502
+ if (propParts) {
503
+ const propName = propParts[1];
504
+ const isOptional = !!propParts[2];
505
+ const propType = propParts[3];
506
+ if (!isOptional) {
507
+ required.push(propName);
508
+ }
509
+ switch (propType) {
510
+ case "string":
511
+ properties[propName] = { type: "string" };
512
+ break;
513
+ case "number":
514
+ properties[propName] = { type: "number" };
515
+ break;
516
+ case "boolean":
517
+ properties[propName] = { type: "boolean" };
518
+ break;
519
+ default:
520
+ properties[propName] = { type: "object" };
521
+ }
522
+ }
523
+ });
524
+ basicSchema = {
525
+ type: "object",
526
+ properties,
527
+ required: required.length > 0 ? required : void 0
528
+ };
529
+ }
530
+ if (member.toolDecoratorText) {
531
+ const oldDecoratorText = member.toolDecoratorText;
532
+ const hasSecondParam = /^@tool\s*\(\s*(['"]).*\1\s*,/.test(oldDecoratorText);
533
+ let newDecoratorText;
534
+ if (hasSecondParam) {
535
+ newDecoratorText = oldDecoratorText.replace(
536
+ /^(@tool\s*\(\s*(['"]).*\2\s*),\s*(?:\S.*)?\)/,
537
+ `$1, ${JSON.stringify(basicSchema, null, 2)})`
538
+ );
539
+ } else {
540
+ newDecoratorText = oldDecoratorText.replace(
541
+ /^(@tool\s*\(\s*(['"]).*\2\s*)\)/,
542
+ `$1, ${JSON.stringify(basicSchema, null, 2)})`
543
+ );
544
+ }
545
+ debugLog(`\u4F7F\u7528\u5907\u7528\u65B9\u6CD5\u66F4\u65B0 tool \u88C5\u9970\u5668:`);
546
+ debugLog(` \u65E7: ${oldDecoratorText}`);
547
+ debugLog(` \u65B0: ${newDecoratorText.substring(0, 50)}...`);
548
+ sourceCode = sourceCode.replace(oldDecoratorText, newDecoratorText);
549
+ updatedDecoratorsCount++;
550
+ }
551
+ } else {
552
+ debugLog(`\u8B66\u544A: \u65B9\u6CD5 ${memberName} \u6CA1\u6709\u53C2\u6570\u7C7B\u578B`);
553
+ }
554
+ } else {
555
+ debugLog(`\u8B66\u544A: \u672A\u627E\u5230\u65B9\u6CD5 ${memberName}`);
556
+ }
557
+ } else {
558
+ debugLog(`\u8B66\u544A: \u63D2\u4EF6 ${pluginClass.name} \u7C7B\u578B\u4E0D\u662F\u5BF9\u8C61\u5B57\u9762\u91CF`);
559
+ }
560
+ } else {
561
+ debugLog(`\u8B66\u544A: \u672A\u627E\u5230\u63D2\u4EF6 ${pluginClass.name}`);
562
+ }
563
+ } catch (backupError) {
564
+ debugLog(`\u5907\u7528\u65B9\u6CD5\u4E5F\u5931\u8D25:`, backupError);
565
+ }
566
+ }
567
+ }
568
+ } else {
569
+ debugLog(`\u8BE5\u63D2\u4EF6\u6CA1\u6709\u5E26 tool \u88C5\u9970\u5668\u7684\u6210\u5458`);
570
+ }
571
+ }
572
+ try {
573
+ yield fs__default.remove(tempTypesDir);
574
+ debugLog(`\u5DF2\u6E05\u7406\u4E34\u65F6\u6587\u4EF6: ${tempTypesDir}`);
575
+ } catch (cleanupError) {
576
+ debugLog(`\u6E05\u7406\u4E34\u65F6\u6587\u4EF6\u5931\u8D25\uFF0C\u53EF\u624B\u52A8\u5220\u9664: ${tempTypesDir}`, cleanupError);
577
+ }
578
+ yield fs__default.writeFile(file, sourceCode, "utf-8");
579
+ spinner.succeed(`\u2705 \u6210\u529F\u66F4\u65B0 ${updatedDecoratorsCount} \u4E2A tool \u88C5\u9970\u5668\u7684 JSON Schema`);
580
+ console.log(chalk__default.green(`\u6587\u4EF6\u5DF2\u66F4\u65B0: ${chalk__default.cyan(file)}`));
581
+ } catch (error) {
582
+ console.error("\u5904\u7406 PluginTools \u63A5\u53E3\u5B9A\u4E49\u5931\u8D25:", error);
583
+ throw error;
584
+ }
585
+ } else {
586
+ console.log("\u672A\u627E\u5230 PluginTools \u63A5\u53E3\uFF0C\u65E0\u6CD5\u751F\u6210 JSON Schema");
587
+ }
588
+ } else {
589
+ yield fs__default.writeFile(file, sourceCode, "utf-8");
590
+ spinner.warn("\u26A0\uFE0F \u672A\u627E\u5230\u53EF\u5904\u7406\u7684\u63D2\u4EF6\u7C7B\uFF0C\u6587\u4EF6\u672A\u505A\u4FEE\u6539");
591
+ }
592
+ } catch (error) {
593
+ spinner.fail("\u274C \u64CD\u4F5C\u5931\u8D25");
594
+ console.error(chalk__default.red(error));
595
+ }
596
+ }));
168
597
  function getKnotxPackageVersions() {
169
598
  return __async(this, null, function* () {
170
599
  const knotxVersions = {};
package/dist/index.js CHANGED
@@ -8,6 +8,8 @@ import { Command } from 'commander';
8
8
  import fs from 'fs-extra';
9
9
  import inquirer from 'inquirer';
10
10
  import ora from 'ora';
11
+ import ts from 'typescript';
12
+ import * as TJS from 'typescript-json-schema';
11
13
 
12
14
  var __defProp = Object.defineProperty;
13
15
  var __defProps = Object.defineProperties;
@@ -154,6 +156,419 @@ program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u76
154
156
  console.error(chalk.red(error));
155
157
  }
156
158
  }));
159
+ program.command("generate-jsonschema").aliases(["gen-schema", "schema"]).description("\u6839\u636E PluginTools \u7C7B\u578B\u58F0\u660E\u751F\u6210 JSON Schema \u5E76\u66F4\u65B0 @tool \u88C5\u9970\u5668").argument("<file>", "TypeScript \u6587\u4EF6\u8DEF\u5F84").option("-d, --debug", "\u8F93\u51FA\u8BE6\u7EC6\u7684\u8C03\u8BD5\u4FE1\u606F", false).action((file, options) => __async(undefined, null, function* () {
160
+ const spinner = ora("\u{1F50D} \u6B63\u5728\u751F\u6210 JSON Schema...").start();
161
+ const debugLog = (message, ...args) => {
162
+ if (options.debug) {
163
+ console.log(message, ...args);
164
+ }
165
+ };
166
+ try {
167
+ let findPluginToolsInterface = function(node) {
168
+ if (ts.isModuleDeclaration(node) && node.name) {
169
+ const moduleName = ts.isStringLiteral(node.name) ? node.name.text : node.name.getText();
170
+ if (moduleName.includes("@knotx/core")) {
171
+ debugLog("\u627E\u5230\u6A21\u5757\u58F0\u660E:", moduleName);
172
+ if (node.body && ts.isModuleBlock(node.body)) {
173
+ node.body.statements.forEach((statement) => {
174
+ if (ts.isInterfaceDeclaration(statement) && statement.name && statement.name.text === "PluginTools") {
175
+ pluginToolsInterface = statement;
176
+ debugLog("\u627E\u5230 PluginTools \u63A5\u53E3:", statement.name.text, "\uFF0C\u5305\u542B", statement.members.length, "\u4E2A\u6210\u5458");
177
+ statement.members.forEach((member) => {
178
+ if (ts.isPropertySignature(member) && member.name) {
179
+ const memberName = ts.isIdentifier(member.name) ? member.name.text : member.name.getText();
180
+ debugLog("- \u6210\u5458:", memberName);
181
+ if (!pluginNames.includes(memberName)) {
182
+ pluginNames.push(memberName);
183
+ }
184
+ }
185
+ });
186
+ }
187
+ });
188
+ }
189
+ }
190
+ }
191
+ ts.forEachChild(node, findPluginToolsInterface);
192
+ }, findPluginClasses = function(node) {
193
+ if (ts.isClassDeclaration(node) && node.name) {
194
+ const className = node.name.text;
195
+ debugLog(`\u68C0\u67E5\u7C7B: ${className}`);
196
+ let isPlugin = false;
197
+ let pluginGenericType = "";
198
+ if (node.heritageClauses) {
199
+ for (const clause of node.heritageClauses) {
200
+ for (const type of clause.types) {
201
+ const expr = type.expression.getText(sourceFile);
202
+ if (expr === "BasePlugin") {
203
+ isPlugin = true;
204
+ if (type.typeArguments && type.typeArguments.length > 0) {
205
+ pluginGenericType = type.typeArguments[0].getText(sourceFile);
206
+ pluginGenericType = pluginGenericType.replace(/['"]/g, "");
207
+ debugLog(` \u63D2\u4EF6\u6CDB\u578B\u7C7B\u578B: ${pluginGenericType}`);
208
+ }
209
+ break;
210
+ }
211
+ }
212
+ }
213
+ }
214
+ let pluginName;
215
+ const members = [];
216
+ if (isPlugin) {
217
+ debugLog(` \u662FBasePlugin\u7684\u5B50\u7C7B`);
218
+ if (node.members) {
219
+ node.members.forEach((member) => {
220
+ if (ts.isPropertyDeclaration(member) && member.name && ts.isIdentifier(member.name) && member.name.text === "name" && member.initializer) {
221
+ const nameText = member.initializer.getText(sourceFile);
222
+ debugLog(` \u627E\u5230name\u5C5E\u6027: ${nameText}`);
223
+ const cleanNameText = nameText.replace(/['"]|as\s+const/g, "").trim();
224
+ debugLog(` \u6E05\u7406\u540E\u7684name: ${cleanNameText}`);
225
+ if (pluginNames.includes(cleanNameText)) {
226
+ pluginName = cleanNameText;
227
+ debugLog(` \u5339\u914D\u5230\u63D2\u4EF6\u540D\u79F0: ${cleanNameText}`);
228
+ }
229
+ }
230
+ const memberName = member.name ? ts.isIdentifier(member.name) ? member.name.text : member.name.getText(sourceFile) : "\u672A\u547D\u540D\u6210\u5458";
231
+ debugLog(` \u68C0\u67E5\u6210\u5458: ${memberName}`);
232
+ let hasToolDecorator = false;
233
+ let toolDecoratorText;
234
+ try {
235
+ if (typeof ts.getDecorators === "function") {
236
+ const decorators = ts.getDecorators(member);
237
+ if (decorators && decorators.length > 0) {
238
+ debugLog(` \u4F7F\u7528getDecorators\u65B9\u6CD5\u627E\u5230\u88C5\u9970\u5668: ${decorators.length}\u4E2A`);
239
+ for (const decorator of decorators) {
240
+ const decoratorText = decorator.getText(sourceFile);
241
+ debugLog(` \u88C5\u9970\u5668: ${decoratorText}`);
242
+ if (decoratorText.startsWith("@tool")) {
243
+ hasToolDecorator = true;
244
+ toolDecoratorText = decoratorText;
245
+ debugLog(` \u627E\u5230tool\u88C5\u9970\u5668: ${decoratorText}`);
246
+ break;
247
+ }
248
+ }
249
+ } else {
250
+ debugLog(` \u6CA1\u6709\u627E\u5230\u88C5\u9970\u5668(getDecorators)`);
251
+ }
252
+ } else {
253
+ debugLog(` ts.getDecorators\u65B9\u6CD5\u4E0D\u53EF\u7528`);
254
+ }
255
+ } catch (err) {
256
+ debugLog(` \u83B7\u53D6\u88C5\u9970\u5668\u65F6\u51FA\u9519:`, err);
257
+ }
258
+ members.push({
259
+ name: memberName,
260
+ hasToolDecorator,
261
+ toolDecoratorText,
262
+ node: member
263
+ });
264
+ });
265
+ }
266
+ if (pluginName) {
267
+ debugLog(`
268
+ \u627E\u5230\u63D2\u4EF6\u7C7B: ${className}, \u63D2\u4EF6\u540D\u79F0: ${pluginName}`);
269
+ const membersWithDecorator = members.filter((m) => m.hasToolDecorator);
270
+ if (membersWithDecorator.length > 0) {
271
+ debugLog(`\u8BE5\u63D2\u4EF6\u6709 ${membersWithDecorator.length} \u4E2A\u6210\u5458\u4F7F\u7528\u4E86 tool \u88C5\u9970\u5668:`);
272
+ membersWithDecorator.forEach((member) => {
273
+ debugLog(`- ${member.name}: ${member.toolDecoratorText}`);
274
+ });
275
+ } else {
276
+ debugLog("\u8BE5\u63D2\u4EF6\u6CA1\u6709\u6210\u5458\u4F7F\u7528 tool \u88C5\u9970\u5668");
277
+ }
278
+ pluginClasses.push({
279
+ className,
280
+ name: pluginName,
281
+ members
282
+ });
283
+ } else if (pluginGenericType) {
284
+ debugLog(`
285
+ \u627E\u5230\u6F5C\u5728\u63D2\u4EF6\u7C7B: ${className}, \u6CDB\u578B\u7C7B\u578B: ${pluginGenericType}`);
286
+ const potentialPluginName = pluginGenericType;
287
+ if (pluginNames.includes(potentialPluginName)) {
288
+ debugLog(`\u6839\u636E\u6CDB\u578B\u7C7B\u578B\u63A8\u65AD\u63D2\u4EF6\u540D\u79F0: ${potentialPluginName}`);
289
+ const membersWithDecorator = members.filter((m) => m.hasToolDecorator);
290
+ if (membersWithDecorator.length > 0) {
291
+ debugLog(`\u8BE5\u63D2\u4EF6\u6709 ${membersWithDecorator.length} \u4E2A\u6210\u5458\u4F7F\u7528\u4E86 tool \u88C5\u9970\u5668:`);
292
+ membersWithDecorator.forEach((member) => {
293
+ debugLog(`- ${member.name}: ${member.toolDecoratorText}`);
294
+ });
295
+ } else {
296
+ debugLog("\u8BE5\u63D2\u4EF6\u6CA1\u6709\u6210\u5458\u4F7F\u7528 tool \u88C5\u9970\u5668");
297
+ }
298
+ pluginClasses.push({
299
+ className,
300
+ name: potentialPluginName,
301
+ members
302
+ });
303
+ } else {
304
+ debugLog(`\u6CDB\u578B\u7C7B\u578B ${potentialPluginName} \u4E0D\u5339\u914D\u4EFB\u4F55\u5DF2\u77E5\u63D2\u4EF6\u540D\u79F0`);
305
+ }
306
+ }
307
+ }
308
+ }
309
+ ts.forEachChild(node, findPluginClasses);
310
+ };
311
+ const program2 = TJS.getProgramFromFiles([file], {
312
+ strictNullChecks: true
313
+ });
314
+ const sourceFile = program2.getSourceFile(file);
315
+ if (!sourceFile) {
316
+ throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u6E90\u6587\u4EF6");
317
+ }
318
+ let sourceCode = yield fs.readFile(file, "utf-8");
319
+ debugLog("\u5F00\u59CB\u67E5\u627E PluginTools \u63A5\u53E3...");
320
+ let pluginToolsInterface;
321
+ const pluginNames = [];
322
+ sourceFile.forEachChild(findPluginToolsInterface);
323
+ if (!pluginToolsInterface) {
324
+ debugLog("\u672A\u627E\u5230 PluginTools \u63A5\u53E3");
325
+ } else {
326
+ debugLog(`
327
+ \u627E\u5230\u7684\u63D2\u4EF6\u540D\u79F0:`, pluginNames);
328
+ if (pluginNames.length === 0) {
329
+ debugLog("\u8B66\u544A: \u672A\u627E\u5230\u4EFB\u4F55\u63D2\u4EF6\u540D\u79F0\uFF0C\u8BF7\u786E\u8BA4 PluginTools \u63A5\u53E3\u6269\u5C55\u662F\u5426\u6B63\u786E");
330
+ }
331
+ }
332
+ const pluginClasses = [];
333
+ debugLog("\n\u5F00\u59CB\u67E5\u627E\u63D2\u4EF6\u7C7B...");
334
+ sourceFile.forEachChild(findPluginClasses);
335
+ if (pluginClasses.length === 0) {
336
+ debugLog("\u672A\u627E\u5230\u5BF9\u5E94\u7684\u63D2\u4EF6\u7C7B");
337
+ }
338
+ if (pluginClasses.length > 0) {
339
+ debugLog("\n\u5F00\u59CB\u751F\u6210 JSON Schema \u5E76\u66F4\u65B0 tool \u88C5\u9970\u5668...");
340
+ if (pluginToolsInterface) {
341
+ debugLog("\u63D0\u53D6 PluginTools \u63A5\u53E3\u5B9A\u4E49...");
342
+ const tempTypesDir = path.join(path.dirname(file), ".temp_types");
343
+ const tempTypesFile = path.join(tempTypesDir, "plugin-tools.d.ts");
344
+ try {
345
+ yield fs.ensureDir(tempTypesDir);
346
+ let interfaceContent = "/**\n * \u81EA\u52A8\u751F\u6210\u7684\u7C7B\u578B\u5B9A\u4E49\u6587\u4EF6\n */\n\n";
347
+ const paramTypeDefs = [];
348
+ interfaceContent += "export interface PluginTools {\n";
349
+ for (const member of pluginToolsInterface.members) {
350
+ if (ts.isPropertySignature(member)) {
351
+ const memberText = member.getText(sourceFile);
352
+ interfaceContent += ` ${memberText}
353
+ `;
354
+ if (member.name) {
355
+ const pluginName = ts.isIdentifier(member.name) ? member.name.text : member.name.getText(sourceFile);
356
+ if (member.type && ts.isTypeLiteralNode(member.type)) {
357
+ for (const pluginMember of member.type.members) {
358
+ if (ts.isPropertySignature(pluginMember) && pluginMember.name) {
359
+ const methodName = ts.isIdentifier(pluginMember.name) ? pluginMember.name.text : pluginMember.name.getText(sourceFile);
360
+ if (pluginMember.type && ts.isFunctionTypeNode(pluginMember.type) && pluginMember.type.parameters.length > 0 && pluginMember.type.parameters[0].type) {
361
+ const paramTypeText = pluginMember.type.parameters[0].type.getText(sourceFile);
362
+ const paramTypeDef = `// \u53C2\u6570\u7C7B\u578B: ${pluginName}.${methodName}
363
+ export type ${pluginName}_${methodName}_ParamType = ${paramTypeText};
364
+ `;
365
+ paramTypeDefs.push(paramTypeDef);
366
+ }
367
+ }
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+ interfaceContent += "}\n\n";
374
+ interfaceContent += paramTypeDefs.join("\n");
375
+ debugLog(`\u63D0\u53D6\u7684\u63A5\u53E3\u5B9A\u4E49:
376
+ ${interfaceContent}`);
377
+ yield fs.writeFile(tempTypesFile, interfaceContent);
378
+ debugLog(`\u63A5\u53E3\u5B9A\u4E49\u5DF2\u5199\u5165\u4E34\u65F6\u6587\u4EF6: ${tempTypesFile}`);
379
+ const tempProgram = TJS.getProgramFromFiles([tempTypesFile], {
380
+ strictNullChecks: true,
381
+ lib: ["ESNext"]
382
+ });
383
+ const generator = TJS.buildGenerator(tempProgram, {
384
+ required: true,
385
+ noExtraProps: true,
386
+ skipLibCheck: true
387
+ });
388
+ if (!generator) {
389
+ throw new Error("\u65E0\u6CD5\u521B\u5EFA JSON Schema \u751F\u6210\u5668");
390
+ }
391
+ const allSymbols = generator.getUserSymbols();
392
+ debugLog("\u53EF\u7528\u7684\u7C7B\u578B\u7B26\u53F7:", allSymbols);
393
+ let updatedDecoratorsCount = 0;
394
+ for (const pluginClass of pluginClasses) {
395
+ debugLog(`
396
+ \u5904\u7406\u63D2\u4EF6: ${pluginClass.className} (${pluginClass.name})`);
397
+ const membersWithDecorator = pluginClass.members.filter((m) => m.hasToolDecorator);
398
+ if (membersWithDecorator.length > 0) {
399
+ debugLog(`\u5904\u7406 ${membersWithDecorator.length} \u4E2A\u5E26 tool \u88C5\u9970\u5668\u7684\u6210\u5458`);
400
+ for (const member of membersWithDecorator) {
401
+ const memberName = member.name;
402
+ debugLog(`\u5904\u7406\u6210\u5458: ${memberName}`);
403
+ try {
404
+ const typeName = `${pluginClass.name}_${memberName}_ParamType`;
405
+ debugLog(`\u67E5\u627E\u7C7B\u578B: ${typeName}`);
406
+ if (allSymbols.includes(typeName)) {
407
+ const schema = generator.getSchemaForSymbol(typeName);
408
+ if (schema) {
409
+ debugLog(`\u6210\u529F\u751F\u6210 JSON Schema:`, `${JSON.stringify(schema).substring(0, 50)}...`);
410
+ if (member.toolDecoratorText) {
411
+ const oldDecoratorText = member.toolDecoratorText;
412
+ const hasSecondParam = /^@tool\s*\(\s*(['"]).*\1\s*,/.test(oldDecoratorText);
413
+ let newDecoratorText;
414
+ if (hasSecondParam) {
415
+ newDecoratorText = oldDecoratorText.replace(
416
+ /^(@tool\s*\(\s*(['"]).*\2\s*),\s*(?:\S.*)?\)/,
417
+ `$1, ${JSON.stringify(schema, null, 2)})`
418
+ );
419
+ } else {
420
+ newDecoratorText = oldDecoratorText.replace(
421
+ /^(@tool\s*\(\s*(['"]).*\2\s*)\)/,
422
+ `$1, ${JSON.stringify(schema, null, 2)})`
423
+ );
424
+ }
425
+ debugLog(`\u66F4\u65B0 tool \u88C5\u9970\u5668:`);
426
+ debugLog(` \u65E7: ${oldDecoratorText}`);
427
+ debugLog(` \u65B0: ${newDecoratorText.substring(0, 50)}...`);
428
+ sourceCode = sourceCode.replace(oldDecoratorText, newDecoratorText);
429
+ updatedDecoratorsCount++;
430
+ }
431
+ } else {
432
+ debugLog(`\u8B66\u544A: \u4E3A ${typeName} \u751F\u6210Schema\u5931\u8D25\uFF0C\u4F46\u7C7B\u578B\u5E94\u8BE5\u5B58\u5728`);
433
+ throw new Error(`\u65E0\u6CD5\u4E3A\u5B58\u5728\u7684\u7C7B\u578B ${typeName} \u751F\u6210Schema`);
434
+ }
435
+ } else {
436
+ debugLog(`\u672A\u627E\u5230\u547D\u540D\u7C7B\u578B ${typeName}\uFF0C\u5C1D\u8BD5\u5176\u4ED6\u65B9\u6CD5...`);
437
+ throw new Error(`\u7C7B\u578B ${typeName} \u4E0D\u5728\u53EF\u7528\u7B26\u53F7\u5217\u8868\u4E2D`);
438
+ }
439
+ } catch (error) {
440
+ debugLog(`\u5904\u7406\u6210\u5458 ${memberName} \u65F6\u51FA\u9519:`, error);
441
+ debugLog(`\u5C1D\u8BD5\u5907\u7528\u65B9\u6CD5...`);
442
+ try {
443
+ const pluginProp = pluginToolsInterface.members.find((member2) => {
444
+ if (ts.isPropertySignature(member2) && member2.name) {
445
+ const propName = ts.isIdentifier(member2.name) ? member2.name.text : member2.name.getText(sourceFile);
446
+ return propName === pluginClass.name;
447
+ }
448
+ return false;
449
+ });
450
+ if (pluginProp && ts.isPropertySignature(pluginProp) && pluginProp.type) {
451
+ if (ts.isTypeLiteralNode(pluginProp.type)) {
452
+ const methodProp = pluginProp.type.members.find((m) => {
453
+ if (ts.isPropertySignature(m) && m.name) {
454
+ const methodName = ts.isIdentifier(m.name) ? m.name.text : m.name.getText(sourceFile);
455
+ return methodName === memberName;
456
+ }
457
+ return false;
458
+ });
459
+ if (methodProp && ts.isPropertySignature(methodProp) && methodProp.type) {
460
+ if (ts.isFunctionTypeNode(methodProp.type) && methodProp.type.parameters.length > 0 && methodProp.type.parameters[0].type) {
461
+ const paramTypeText = methodProp.type.parameters[0].type.getText(sourceFile);
462
+ debugLog(`\u627E\u5230\u53C2\u6570\u7C7B\u578B: ${paramTypeText}`);
463
+ let basicSchema = { type: "object" };
464
+ if (paramTypeText === "string") {
465
+ basicSchema = { type: "string" };
466
+ } else if (paramTypeText === "number") {
467
+ basicSchema = { type: "number" };
468
+ } else if (paramTypeText === "boolean") {
469
+ basicSchema = { type: "boolean" };
470
+ } else if (paramTypeText.startsWith("{") && paramTypeText.endsWith("}")) {
471
+ const content = paramTypeText.slice(1, -1).trim();
472
+ const properties = {};
473
+ const required = [];
474
+ const matches = content.match(/(\w+)(\?)?:\s*(string|number|boolean|\w+)/g) || [];
475
+ matches.forEach((propMatch) => {
476
+ const propParts = /(\w+)(\?)?:\s*(string|number|boolean|\w+)/.exec(propMatch);
477
+ if (propParts) {
478
+ const propName = propParts[1];
479
+ const isOptional = !!propParts[2];
480
+ const propType = propParts[3];
481
+ if (!isOptional) {
482
+ required.push(propName);
483
+ }
484
+ switch (propType) {
485
+ case "string":
486
+ properties[propName] = { type: "string" };
487
+ break;
488
+ case "number":
489
+ properties[propName] = { type: "number" };
490
+ break;
491
+ case "boolean":
492
+ properties[propName] = { type: "boolean" };
493
+ break;
494
+ default:
495
+ properties[propName] = { type: "object" };
496
+ }
497
+ }
498
+ });
499
+ basicSchema = {
500
+ type: "object",
501
+ properties,
502
+ required: required.length > 0 ? required : void 0
503
+ };
504
+ }
505
+ if (member.toolDecoratorText) {
506
+ const oldDecoratorText = member.toolDecoratorText;
507
+ const hasSecondParam = /^@tool\s*\(\s*(['"]).*\1\s*,/.test(oldDecoratorText);
508
+ let newDecoratorText;
509
+ if (hasSecondParam) {
510
+ newDecoratorText = oldDecoratorText.replace(
511
+ /^(@tool\s*\(\s*(['"]).*\2\s*),\s*(?:\S.*)?\)/,
512
+ `$1, ${JSON.stringify(basicSchema, null, 2)})`
513
+ );
514
+ } else {
515
+ newDecoratorText = oldDecoratorText.replace(
516
+ /^(@tool\s*\(\s*(['"]).*\2\s*)\)/,
517
+ `$1, ${JSON.stringify(basicSchema, null, 2)})`
518
+ );
519
+ }
520
+ debugLog(`\u4F7F\u7528\u5907\u7528\u65B9\u6CD5\u66F4\u65B0 tool \u88C5\u9970\u5668:`);
521
+ debugLog(` \u65E7: ${oldDecoratorText}`);
522
+ debugLog(` \u65B0: ${newDecoratorText.substring(0, 50)}...`);
523
+ sourceCode = sourceCode.replace(oldDecoratorText, newDecoratorText);
524
+ updatedDecoratorsCount++;
525
+ }
526
+ } else {
527
+ debugLog(`\u8B66\u544A: \u65B9\u6CD5 ${memberName} \u6CA1\u6709\u53C2\u6570\u7C7B\u578B`);
528
+ }
529
+ } else {
530
+ debugLog(`\u8B66\u544A: \u672A\u627E\u5230\u65B9\u6CD5 ${memberName}`);
531
+ }
532
+ } else {
533
+ debugLog(`\u8B66\u544A: \u63D2\u4EF6 ${pluginClass.name} \u7C7B\u578B\u4E0D\u662F\u5BF9\u8C61\u5B57\u9762\u91CF`);
534
+ }
535
+ } else {
536
+ debugLog(`\u8B66\u544A: \u672A\u627E\u5230\u63D2\u4EF6 ${pluginClass.name}`);
537
+ }
538
+ } catch (backupError) {
539
+ debugLog(`\u5907\u7528\u65B9\u6CD5\u4E5F\u5931\u8D25:`, backupError);
540
+ }
541
+ }
542
+ }
543
+ } else {
544
+ debugLog(`\u8BE5\u63D2\u4EF6\u6CA1\u6709\u5E26 tool \u88C5\u9970\u5668\u7684\u6210\u5458`);
545
+ }
546
+ }
547
+ try {
548
+ yield fs.remove(tempTypesDir);
549
+ debugLog(`\u5DF2\u6E05\u7406\u4E34\u65F6\u6587\u4EF6: ${tempTypesDir}`);
550
+ } catch (cleanupError) {
551
+ debugLog(`\u6E05\u7406\u4E34\u65F6\u6587\u4EF6\u5931\u8D25\uFF0C\u53EF\u624B\u52A8\u5220\u9664: ${tempTypesDir}`, cleanupError);
552
+ }
553
+ yield fs.writeFile(file, sourceCode, "utf-8");
554
+ spinner.succeed(`\u2705 \u6210\u529F\u66F4\u65B0 ${updatedDecoratorsCount} \u4E2A tool \u88C5\u9970\u5668\u7684 JSON Schema`);
555
+ console.log(chalk.green(`\u6587\u4EF6\u5DF2\u66F4\u65B0: ${chalk.cyan(file)}`));
556
+ } catch (error) {
557
+ console.error("\u5904\u7406 PluginTools \u63A5\u53E3\u5B9A\u4E49\u5931\u8D25:", error);
558
+ throw error;
559
+ }
560
+ } else {
561
+ console.log("\u672A\u627E\u5230 PluginTools \u63A5\u53E3\uFF0C\u65E0\u6CD5\u751F\u6210 JSON Schema");
562
+ }
563
+ } else {
564
+ yield fs.writeFile(file, sourceCode, "utf-8");
565
+ spinner.warn("\u26A0\uFE0F \u672A\u627E\u5230\u53EF\u5904\u7406\u7684\u63D2\u4EF6\u7C7B\uFF0C\u6587\u4EF6\u672A\u505A\u4FEE\u6539");
566
+ }
567
+ } catch (error) {
568
+ spinner.fail("\u274C \u64CD\u4F5C\u5931\u8D25");
569
+ console.error(chalk.red(error));
570
+ }
571
+ }));
157
572
  function getKnotxPackageVersions() {
158
573
  return __async(this, null, function* () {
159
574
  const knotxVersions = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knotx/cli",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "CLI tool for Knotx",
5
5
  "author": "boenfu",
6
6
  "license": "MIT",
@@ -35,14 +35,16 @@
35
35
  "commander": "^12.0.0",
36
36
  "fs-extra": "^11.2.0",
37
37
  "inquirer": "^9.2.15",
38
- "ora": "^8.0.1"
38
+ "ora": "^8.0.1",
39
+ "typescript": "~5.5.4",
40
+ "typescript-json-schema": "^0.65.1"
39
41
  },
40
42
  "devDependencies": {
41
43
  "@types/fs-extra": "^11.0.4",
42
44
  "@types/inquirer": "^9.0.7",
43
- "@knotx/build-config": "0.2.11",
44
- "@knotx/eslint-config": "0.2.11",
45
- "@knotx/typescript-config": "0.2.11"
45
+ "@knotx/build-config": "0.2.12",
46
+ "@knotx/eslint-config": "0.2.12",
47
+ "@knotx/typescript-config": "0.2.12"
46
48
  },
47
49
  "scripts": {
48
50
  "build": "unbuild",