@knotx/cli 0.0.2 → 0.0.4

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
@@ -19,6 +19,25 @@ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
19
19
  const inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
20
20
  const ora__default = /*#__PURE__*/_interopDefaultCompat(ora);
21
21
 
22
+ var __defProp = Object.defineProperty;
23
+ var __defProps = Object.defineProperties;
24
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
25
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
26
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
27
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
28
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
29
+ var __spreadValues = (a, b) => {
30
+ for (var prop in b || (b = {}))
31
+ if (__hasOwnProp.call(b, prop))
32
+ __defNormalProp(a, prop, b[prop]);
33
+ if (__getOwnPropSymbols)
34
+ for (var prop of __getOwnPropSymbols(b)) {
35
+ if (__propIsEnum.call(b, prop))
36
+ __defNormalProp(a, prop, b[prop]);
37
+ }
38
+ return a;
39
+ };
40
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
41
  var __async = (__this, __arguments, generator) => {
23
42
  return new Promise((resolve, reject) => {
24
43
  var fulfilled = (value) => {
@@ -42,7 +61,7 @@ var __async = (__this, __arguments, generator) => {
42
61
  const templatesDir = path__default.resolve(__dirname, "..", "templates");
43
62
  const program = new commander.Command();
44
63
  program.name("knotx").description("Knotx CLI - \u521B\u5EFA\u548C\u7BA1\u7406Knotx\u63D2\u4EF6").version("0.0.1");
45
- program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684Knotx\u63D2\u4EF6").action(() => __async(undefined, null, function* () {
64
+ program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684Knotx\u63D2\u4EF6\uFF0C\u5305\u542B\u5F00\u53D1\u73AF\u5883\u548C\u6F14\u793A playground").action(() => __async(undefined, null, function* () {
46
65
  console.log(chalk__default.blue("\u{1F539} \u6B22\u8FCE\u4F7F\u7528 Knotx \u63D2\u4EF6\u521B\u5EFA\u5DE5\u5177\uFF01"));
47
66
  const answers = yield inquirer__default.prompt([
48
67
  {
@@ -91,16 +110,34 @@ program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u76
91
110
  spinner = ora__default("\u{1F4C4} \u521B\u5EFA README.md...").start();
92
111
  yield createReadme(targetDir, pluginName);
93
112
  spinner.succeed("\u{1F4C4} README.md \u521B\u5EFA\u6210\u529F");
113
+ spinner = ora__default("\u{1F4C4} \u521B\u5EFA .gitignore \u6587\u4EF6...").start();
114
+ yield createGitignore(targetDir);
115
+ spinner.succeed("\u{1F4C4} .gitignore \u521B\u5EFA\u6210\u529F");
116
+ spinner = ora__default("\u{1F527} \u521D\u59CB\u5316 Git \u4ED3\u5E93...").start();
117
+ try {
118
+ initGitRepo(targetDir);
119
+ spinner.succeed("\u{1F527} Git \u4ED3\u5E93\u521D\u59CB\u5316\u6210\u529F");
120
+ } catch (error) {
121
+ spinner.warn("\u26A0\uFE0F Git \u4ED3\u5E93\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u521D\u59CB\u5316");
122
+ console.warn(chalk__default.yellow(` \u53EF\u80FD\u7684\u539F\u56E0: ${error.message}`));
123
+ }
94
124
  console.log(chalk__default.green(`
95
125
  \u2705 \u63D2\u4EF6 ${chalk__default.bold(fullPluginName)} \u521B\u5EFA\u6210\u529F\uFF01`));
96
126
  console.log(`
97
127
  \u{1F4C1} \u63D2\u4EF6\u76EE\u5F55: ${chalk__default.cyan(targetDir)}`);
98
128
  console.log(`
99
- \u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u4EE5\u5B89\u88C5\u4F9D\u8D56\u5E76\u6784\u5EFA:
129
+ \u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u4EE5\u5B89\u88C5\u4F9D\u8D56\u5E76\u5F00\u59CB\u5F00\u53D1:
100
130
  `);
101
131
  console.log(chalk__default.cyan(` cd ${path__default.relative(process__default.cwd(), targetDir)}`));
102
132
  console.log(chalk__default.cyan(" pnpm install"));
103
133
  console.log(chalk__default.cyan(" pnpm build"));
134
+ console.log(chalk__default.cyan(" pnpm dev # \u542F\u52A8\u5F00\u53D1\u670D\u52A1\u5668\uFF0C\u8FD0\u884C playground"));
135
+ console.log(`
136
+ \u{1F680} \u63D2\u4EF6\u5F00\u53D1\u8BF4\u660E:`);
137
+ console.log(` 1. \u4E3B\u8981\u4EE3\u7801\u4F4D\u4E8E ${chalk__default.yellow("src/")} \u76EE\u5F55`);
138
+ console.log(` 2. \u5F00\u53D1\u73AF\u5883\uFF08Playground\uFF09\u4F4D\u4E8E ${chalk__default.yellow("playground/")} \u76EE\u5F55`);
139
+ console.log(` 3. \u8FD0\u884C ${chalk__default.yellow("pnpm dev")} \u542F\u52A8 Vite \u5F00\u53D1\u670D\u52A1\u5668\uFF0C\u8BBF\u95EE ${chalk__default.blue("http://localhost:5173")} \u67E5\u770B\u6F14\u793A\u9875\u9762`);
140
+ console.log(` 4. \u5BF9\u4EE3\u7801\u7684\u4FEE\u6539\u4F1A\u81EA\u52A8\u70ED\u91CD\u8F7D\uFF0C\u5B9E\u65F6\u67E5\u770B\u6548\u679C`);
104
141
  } catch (error) {
105
142
  spinner.fail("\u274C \u521B\u5EFA\u63D2\u4EF6\u5931\u8D25");
106
143
  console.error(chalk__default.red(error));
@@ -110,7 +147,16 @@ function getKnotxPackageVersions() {
110
147
  return __async(this, null, function* () {
111
148
  const knotxVersions = {};
112
149
  try {
113
- const packages = ["@knotx/core", "@knotx/decorators", "@knotx/jsx", "@knotx/build-config", "@knotx/eslint-config", "@knotx/typescript-config"];
150
+ const packages = [
151
+ "@knotx/core",
152
+ "@knotx/decorators",
153
+ "@knotx/jsx",
154
+ "@knotx/build-config",
155
+ "@knotx/eslint-config",
156
+ "@knotx/typescript-config",
157
+ "@knotx/react",
158
+ "@knotx/plugins-base-render"
159
+ ];
114
160
  const npmRegistry = "https://registry.npmjs.org";
115
161
  for (const pkg of packages) {
116
162
  try {
@@ -118,19 +164,19 @@ function getKnotxPackageVersions() {
118
164
  knotxVersions[pkg] = `^${version}`;
119
165
  } catch (e) {
120
166
  console.warn(chalk__default.yellow(`\u26A0\uFE0F \u65E0\u6CD5\u83B7\u53D6 ${pkg} \u7684\u6700\u65B0\u7248\u672C\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u7248\u672C`));
121
- knotxVersions[pkg] = "^0.0.1";
167
+ knotxVersions[pkg] = "latest";
122
168
  }
123
169
  }
124
170
  return knotxVersions;
125
171
  } catch (e) {
126
172
  console.warn(chalk__default.yellow("\u26A0\uFE0F \u83B7\u53D6 @knotx \u5305\u7248\u672C\u5931\u8D25\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u7248\u672C"));
127
173
  return {
128
- "@knotx/core": "^0.0.1",
129
- "@knotx/decorators": "^0.0.1",
130
- "@knotx/jsx": "^0.0.1",
131
- "@knotx/build-config": "^0.0.1",
132
- "@knotx/eslint-config": "^0.0.1",
133
- "@knotx/typescript-config": "^0.0.1"
174
+ "@knotx/core": "latest",
175
+ "@knotx/decorators": "latest",
176
+ "@knotx/jsx": "latest",
177
+ "@knotx/build-config": "latest",
178
+ "@knotx/eslint-config": "latest",
179
+ "@knotx/typescript-config": "latest"
134
180
  };
135
181
  }
136
182
  });
@@ -162,7 +208,7 @@ function createPackageJson(targetDir, pluginName, environment, knotxVersions) {
162
208
  ],
163
209
  scripts: {
164
210
  build: "unbuild --failOnWarn=false",
165
- dev: "unbuild --stub",
211
+ dev: "cd ./playground && vite",
166
212
  lint: "eslint .",
167
213
  typecheck: "tsc --noEmit"
168
214
  },
@@ -173,6 +219,7 @@ function createPackageJson(targetDir, pluginName, environment, knotxVersions) {
173
219
  "@knotx/jsx": knotxVersions["@knotx/jsx"]
174
220
  },
175
221
  devDependencies: {
222
+ "@babel/plugin-proposal-decorators": "^7.25.9",
176
223
  "@knotx/build-config": knotxVersions["@knotx/build-config"],
177
224
  "@knotx/eslint-config": knotxVersions["@knotx/eslint-config"],
178
225
  "@knotx/typescript-config": knotxVersions["@knotx/typescript-config"],
@@ -187,18 +234,69 @@ function createPackageJson(targetDir, pluginName, environment, knotxVersions) {
187
234
  if (environment === "jsx") ; else if (environment === "react") {
188
235
  packageJson.peerDependencies.react = "^17";
189
236
  packageJson.peerDependencies["react-dom"] = "^17";
237
+ packageJson.devDependencies["@knotx/react"] = knotxVersions["@knotx/react"];
238
+ packageJson.devDependencies["@knotx/plugins-base-render"] = knotxVersions["@knotx/plugins-base-render"];
190
239
  packageJson.devDependencies.react = "^17";
191
240
  packageJson.devDependencies["@vitejs/plugin-react"] = "^4.3.4";
192
241
  packageJson.devDependencies["react-dom"] = "^17";
193
242
  packageJson.devDependencies["@types/react"] = "^17";
194
243
  packageJson.devDependencies["@types/react-dom"] = "^17";
195
244
  }
245
+ const sortedPackageJson = sortObjectKeys(packageJson);
196
246
  yield fs__default.writeFile(
197
247
  path__default.join(targetDir, "package.json"),
198
- JSON.stringify(packageJson, null, 2)
248
+ `${JSON.stringify(sortedPackageJson, null, 2)}
249
+ `
199
250
  );
200
251
  });
201
252
  }
253
+ function sortObjectKeys(obj) {
254
+ const keyOrder = [
255
+ "name",
256
+ "type",
257
+ "version",
258
+ "description",
259
+ "license",
260
+ "publishConfig",
261
+ "sideEffects",
262
+ "exports",
263
+ "main",
264
+ "module",
265
+ "types",
266
+ "files",
267
+ "scripts",
268
+ "peerDependencies",
269
+ "dependencies",
270
+ "devDependencies"
271
+ ];
272
+ const sortedObj = {};
273
+ for (const key of keyOrder) {
274
+ if (key in obj)
275
+ sortedObj[key] = obj[key];
276
+ }
277
+ const remainingKeys = Object.keys(obj).filter((key) => !keyOrder.includes(key)).sort();
278
+ for (const key of remainingKeys) {
279
+ sortedObj[key] = obj[key];
280
+ }
281
+ for (const key of Object.keys(sortedObj)) {
282
+ if (typeof sortedObj[key] === "object" && sortedObj[key] !== null && !Array.isArray(sortedObj[key])) {
283
+ if (["dependencies", "devDependencies", "peerDependencies"].includes(key)) {
284
+ sortedObj[key] = sortObjectAlphabetically(sortedObj[key]);
285
+ } else {
286
+ sortedObj[key] = sortObjectKeys(sortedObj[key]);
287
+ }
288
+ }
289
+ }
290
+ return sortedObj;
291
+ }
292
+ function sortObjectAlphabetically(obj) {
293
+ const sortedObj = {};
294
+ const sortedKeys = Object.keys(obj).sort();
295
+ for (const key of sortedKeys) {
296
+ sortedObj[key] = obj[key];
297
+ }
298
+ return sortedObj;
299
+ }
202
300
  function createConfigFiles(targetDir) {
203
301
  return __async(this, null, function* () {
204
302
  try {
@@ -250,17 +348,44 @@ function createSourceFiles(targetDir, pluginName, environment) {
250
348
  const pluginContent = pluginTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName));
251
349
  const fileName = `${pluginName}.tsx`;
252
350
  yield fs__default.writeFile(path__default.join(targetDir, "src", fileName), pluginContent);
351
+ yield createPlayground(targetDir, pluginName, environment);
253
352
  } catch (error) {
254
353
  console.error("\u65E0\u6CD5\u8BFB\u53D6\u6A21\u677F\u6587\u4EF6:", error);
255
354
  }
256
355
  });
257
356
  }
357
+ function createPlayground(targetDir, pluginName, environment) {
358
+ return __async(this, null, function* () {
359
+ const playgroundDir = path__default.join(targetDir, "playground");
360
+ yield fs__default.ensureDir(playgroundDir);
361
+ try {
362
+ const viteConfigTemplate = yield fs__default.readFile(path__default.join(templatesDir, "vite.config.ts.template"), "utf-8");
363
+ const htmlTemplate = yield fs__default.readFile(path__default.join(templatesDir, "playground/index.html.template"), "utf-8");
364
+ const tsConfigTemplate = yield fs__default.readFile(path__default.join(templatesDir, "playground/tsconfig.json.template"), "utf-8");
365
+ const isReact = environment === "react";
366
+ const mainTemplate = yield fs__default.readFile(
367
+ path__default.join(templatesDir, `playground/main.${isReact ? "react" : "jsx"}.template`),
368
+ "utf-8"
369
+ );
370
+ const fileExtension = isReact ? "tsx" : "ts";
371
+ const viteConfigContent = viteConfigTemplate.replace(new RegExp("\\{\\{#if isReact\\}\\}(.*?)\\{\\{\\/if\\}\\}", "gs"), isReact ? "$1" : "");
372
+ const htmlContent = htmlTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName)).replace(/\{\{fileExtension\}\}/g, fileExtension);
373
+ const mainContent = mainTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName));
374
+ yield fs__default.writeFile(path__default.join(playgroundDir, "vite.config.ts"), viteConfigContent);
375
+ yield fs__default.writeFile(path__default.join(playgroundDir, "index.html"), htmlContent);
376
+ yield fs__default.writeFile(path__default.join(playgroundDir, `main.${fileExtension}`), mainContent);
377
+ yield fs__default.writeFile(path__default.join(playgroundDir, "tsconfig.json"), tsConfigTemplate);
378
+ } catch (error) {
379
+ console.error("\u8BFB\u53D6 playground \u6A21\u677F\u6587\u4EF6\u5931\u8D25:", error);
380
+ }
381
+ });
382
+ }
258
383
  function createReadme(targetDir, pluginName) {
259
384
  return __async(this, null, function* () {
260
385
  try {
261
386
  const readmeTemplate = yield fs__default.readFile(path__default.join(templatesDir, "README.md.template"), "utf-8");
262
387
  const description = `${capitalize(pluginName)} Plugin for Knotx`;
263
- const readmeContent = readmeTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{description\}\}/g, description);
388
+ const readmeContent = readmeTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName)).replace(/\{\{description\}\}/g, description);
264
389
  yield fs__default.writeFile(path__default.join(targetDir, "README.md"), readmeContent);
265
390
  } catch (error) {
266
391
  console.error("\u65E0\u6CD5\u8BFB\u53D6 README \u6A21\u677F\u6587\u4EF6:", error);
@@ -297,6 +422,67 @@ MIT`;
297
422
  function capitalize(str) {
298
423
  return str.charAt(0).toUpperCase() + str.slice(1);
299
424
  }
425
+ function createGitignore(targetDir) {
426
+ return __async(this, null, function* () {
427
+ try {
428
+ const gitignoreTemplate = yield fs__default.readFile(path__default.join(templatesDir, ".gitignore.template"), "utf-8");
429
+ yield fs__default.writeFile(path__default.join(targetDir, ".gitignore"), gitignoreTemplate);
430
+ } catch (error) {
431
+ console.error("\u65E0\u6CD5\u8BFB\u53D6 .gitignore \u6A21\u677F\u6587\u4EF6:", error);
432
+ const gitignoreContent = `# \u4F9D\u8D56\u76EE\u5F55
433
+ node_modules
434
+
435
+ # \u6784\u5EFA\u4EA7\u7269
436
+ dist
437
+ build
438
+
439
+ # \u65E5\u5FD7\u6587\u4EF6
440
+ logs
441
+ *.log
442
+ npm-debug.log*
443
+ yarn-debug.log*
444
+ yarn-error.log*
445
+ pnpm-debug.log*
446
+
447
+ # \u73AF\u5883\u53D8\u91CF\u6587\u4EF6
448
+ .env
449
+ .env.local
450
+
451
+ # \u7F16\u8F91\u5668\u76EE\u5F55\u548C\u6587\u4EF6
452
+ .vscode
453
+ .idea
454
+ .DS_Store
455
+
456
+ # \u6D4B\u8BD5\u8986\u76D6\u7387
457
+ coverage
458
+ `;
459
+ yield fs__default.writeFile(path__default.join(targetDir, ".gitignore"), gitignoreContent);
460
+ }
461
+ });
462
+ }
463
+ function initGitRepo(targetDir) {
464
+ try {
465
+ node_child_process.execSync("git init", { cwd: targetDir, stdio: "ignore" });
466
+ node_child_process.execSync("git add .", { cwd: targetDir, stdio: "ignore" });
467
+ node_child_process.execSync('git commit -m "Initial commit with Knotx plugin template"', {
468
+ cwd: targetDir,
469
+ stdio: "ignore",
470
+ env: __spreadProps(__spreadValues({}, process__default.env), {
471
+ GIT_AUTHOR_NAME: "Knotx CLI",
472
+ GIT_AUTHOR_EMAIL: "knotx-cli@noreply.github.com",
473
+ GIT_COMMITTER_NAME: "Knotx CLI",
474
+ GIT_COMMITTER_EMAIL: "knotx-cli@noreply.github.com"
475
+ })
476
+ });
477
+ return true;
478
+ } catch (error) {
479
+ if (error instanceof Error) {
480
+ throw new TypeError(`Git \u521D\u59CB\u5316\u5931\u8D25: ${error.message}`);
481
+ } else {
482
+ throw new TypeError(`Git \u521D\u59CB\u5316\u5931\u8D25: ${String(error)}`);
483
+ }
484
+ }
485
+ }
300
486
  program.parse();
301
487
  if (!process__default.argv.slice(2).length) {
302
488
  program.outputHelp();
package/dist/index.mjs CHANGED
@@ -8,6 +8,25 @@ import fs from 'fs-extra';
8
8
  import inquirer from 'inquirer';
9
9
  import ora from 'ora';
10
10
 
11
+ var __defProp = Object.defineProperty;
12
+ var __defProps = Object.defineProperties;
13
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
14
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
17
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
18
+ var __spreadValues = (a, b) => {
19
+ for (var prop in b || (b = {}))
20
+ if (__hasOwnProp.call(b, prop))
21
+ __defNormalProp(a, prop, b[prop]);
22
+ if (__getOwnPropSymbols)
23
+ for (var prop of __getOwnPropSymbols(b)) {
24
+ if (__propIsEnum.call(b, prop))
25
+ __defNormalProp(a, prop, b[prop]);
26
+ }
27
+ return a;
28
+ };
29
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
11
30
  var __async = (__this, __arguments, generator) => {
12
31
  return new Promise((resolve, reject) => {
13
32
  var fulfilled = (value) => {
@@ -31,7 +50,7 @@ var __async = (__this, __arguments, generator) => {
31
50
  const templatesDir = path.resolve(__dirname, "..", "templates");
32
51
  const program = new Command();
33
52
  program.name("knotx").description("Knotx CLI - \u521B\u5EFA\u548C\u7BA1\u7406Knotx\u63D2\u4EF6").version("0.0.1");
34
- program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684Knotx\u63D2\u4EF6").action(() => __async(undefined, null, function* () {
53
+ program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684Knotx\u63D2\u4EF6\uFF0C\u5305\u542B\u5F00\u53D1\u73AF\u5883\u548C\u6F14\u793A playground").action(() => __async(undefined, null, function* () {
35
54
  console.log(chalk.blue("\u{1F539} \u6B22\u8FCE\u4F7F\u7528 Knotx \u63D2\u4EF6\u521B\u5EFA\u5DE5\u5177\uFF01"));
36
55
  const answers = yield inquirer.prompt([
37
56
  {
@@ -80,16 +99,34 @@ program.command("create-plugin").description("\u521B\u5EFA\u4E00\u4E2A\u65B0\u76
80
99
  spinner = ora("\u{1F4C4} \u521B\u5EFA README.md...").start();
81
100
  yield createReadme(targetDir, pluginName);
82
101
  spinner.succeed("\u{1F4C4} README.md \u521B\u5EFA\u6210\u529F");
102
+ spinner = ora("\u{1F4C4} \u521B\u5EFA .gitignore \u6587\u4EF6...").start();
103
+ yield createGitignore(targetDir);
104
+ spinner.succeed("\u{1F4C4} .gitignore \u521B\u5EFA\u6210\u529F");
105
+ spinner = ora("\u{1F527} \u521D\u59CB\u5316 Git \u4ED3\u5E93...").start();
106
+ try {
107
+ initGitRepo(targetDir);
108
+ spinner.succeed("\u{1F527} Git \u4ED3\u5E93\u521D\u59CB\u5316\u6210\u529F");
109
+ } catch (error) {
110
+ spinner.warn("\u26A0\uFE0F Git \u4ED3\u5E93\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u521D\u59CB\u5316");
111
+ console.warn(chalk.yellow(` \u53EF\u80FD\u7684\u539F\u56E0: ${error.message}`));
112
+ }
83
113
  console.log(chalk.green(`
84
114
  \u2705 \u63D2\u4EF6 ${chalk.bold(fullPluginName)} \u521B\u5EFA\u6210\u529F\uFF01`));
85
115
  console.log(`
86
116
  \u{1F4C1} \u63D2\u4EF6\u76EE\u5F55: ${chalk.cyan(targetDir)}`);
87
117
  console.log(`
88
- \u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u4EE5\u5B89\u88C5\u4F9D\u8D56\u5E76\u6784\u5EFA:
118
+ \u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u4EE5\u5B89\u88C5\u4F9D\u8D56\u5E76\u5F00\u59CB\u5F00\u53D1:
89
119
  `);
90
120
  console.log(chalk.cyan(` cd ${path.relative(process.cwd(), targetDir)}`));
91
121
  console.log(chalk.cyan(" pnpm install"));
92
122
  console.log(chalk.cyan(" pnpm build"));
123
+ console.log(chalk.cyan(" pnpm dev # \u542F\u52A8\u5F00\u53D1\u670D\u52A1\u5668\uFF0C\u8FD0\u884C playground"));
124
+ console.log(`
125
+ \u{1F680} \u63D2\u4EF6\u5F00\u53D1\u8BF4\u660E:`);
126
+ console.log(` 1. \u4E3B\u8981\u4EE3\u7801\u4F4D\u4E8E ${chalk.yellow("src/")} \u76EE\u5F55`);
127
+ console.log(` 2. \u5F00\u53D1\u73AF\u5883\uFF08Playground\uFF09\u4F4D\u4E8E ${chalk.yellow("playground/")} \u76EE\u5F55`);
128
+ console.log(` 3. \u8FD0\u884C ${chalk.yellow("pnpm dev")} \u542F\u52A8 Vite \u5F00\u53D1\u670D\u52A1\u5668\uFF0C\u8BBF\u95EE ${chalk.blue("http://localhost:5173")} \u67E5\u770B\u6F14\u793A\u9875\u9762`);
129
+ console.log(` 4. \u5BF9\u4EE3\u7801\u7684\u4FEE\u6539\u4F1A\u81EA\u52A8\u70ED\u91CD\u8F7D\uFF0C\u5B9E\u65F6\u67E5\u770B\u6548\u679C`);
93
130
  } catch (error) {
94
131
  spinner.fail("\u274C \u521B\u5EFA\u63D2\u4EF6\u5931\u8D25");
95
132
  console.error(chalk.red(error));
@@ -99,7 +136,16 @@ function getKnotxPackageVersions() {
99
136
  return __async(this, null, function* () {
100
137
  const knotxVersions = {};
101
138
  try {
102
- const packages = ["@knotx/core", "@knotx/decorators", "@knotx/jsx", "@knotx/build-config", "@knotx/eslint-config", "@knotx/typescript-config"];
139
+ const packages = [
140
+ "@knotx/core",
141
+ "@knotx/decorators",
142
+ "@knotx/jsx",
143
+ "@knotx/build-config",
144
+ "@knotx/eslint-config",
145
+ "@knotx/typescript-config",
146
+ "@knotx/react",
147
+ "@knotx/plugins-base-render"
148
+ ];
103
149
  const npmRegistry = "https://registry.npmjs.org";
104
150
  for (const pkg of packages) {
105
151
  try {
@@ -107,19 +153,19 @@ function getKnotxPackageVersions() {
107
153
  knotxVersions[pkg] = `^${version}`;
108
154
  } catch (e) {
109
155
  console.warn(chalk.yellow(`\u26A0\uFE0F \u65E0\u6CD5\u83B7\u53D6 ${pkg} \u7684\u6700\u65B0\u7248\u672C\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u7248\u672C`));
110
- knotxVersions[pkg] = "^0.0.1";
156
+ knotxVersions[pkg] = "latest";
111
157
  }
112
158
  }
113
159
  return knotxVersions;
114
160
  } catch (e) {
115
161
  console.warn(chalk.yellow("\u26A0\uFE0F \u83B7\u53D6 @knotx \u5305\u7248\u672C\u5931\u8D25\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u7248\u672C"));
116
162
  return {
117
- "@knotx/core": "^0.0.1",
118
- "@knotx/decorators": "^0.0.1",
119
- "@knotx/jsx": "^0.0.1",
120
- "@knotx/build-config": "^0.0.1",
121
- "@knotx/eslint-config": "^0.0.1",
122
- "@knotx/typescript-config": "^0.0.1"
163
+ "@knotx/core": "latest",
164
+ "@knotx/decorators": "latest",
165
+ "@knotx/jsx": "latest",
166
+ "@knotx/build-config": "latest",
167
+ "@knotx/eslint-config": "latest",
168
+ "@knotx/typescript-config": "latest"
123
169
  };
124
170
  }
125
171
  });
@@ -151,7 +197,7 @@ function createPackageJson(targetDir, pluginName, environment, knotxVersions) {
151
197
  ],
152
198
  scripts: {
153
199
  build: "unbuild --failOnWarn=false",
154
- dev: "unbuild --stub",
200
+ dev: "cd ./playground && vite",
155
201
  lint: "eslint .",
156
202
  typecheck: "tsc --noEmit"
157
203
  },
@@ -162,6 +208,7 @@ function createPackageJson(targetDir, pluginName, environment, knotxVersions) {
162
208
  "@knotx/jsx": knotxVersions["@knotx/jsx"]
163
209
  },
164
210
  devDependencies: {
211
+ "@babel/plugin-proposal-decorators": "^7.25.9",
165
212
  "@knotx/build-config": knotxVersions["@knotx/build-config"],
166
213
  "@knotx/eslint-config": knotxVersions["@knotx/eslint-config"],
167
214
  "@knotx/typescript-config": knotxVersions["@knotx/typescript-config"],
@@ -176,18 +223,69 @@ function createPackageJson(targetDir, pluginName, environment, knotxVersions) {
176
223
  if (environment === "jsx") ; else if (environment === "react") {
177
224
  packageJson.peerDependencies.react = "^17";
178
225
  packageJson.peerDependencies["react-dom"] = "^17";
226
+ packageJson.devDependencies["@knotx/react"] = knotxVersions["@knotx/react"];
227
+ packageJson.devDependencies["@knotx/plugins-base-render"] = knotxVersions["@knotx/plugins-base-render"];
179
228
  packageJson.devDependencies.react = "^17";
180
229
  packageJson.devDependencies["@vitejs/plugin-react"] = "^4.3.4";
181
230
  packageJson.devDependencies["react-dom"] = "^17";
182
231
  packageJson.devDependencies["@types/react"] = "^17";
183
232
  packageJson.devDependencies["@types/react-dom"] = "^17";
184
233
  }
234
+ const sortedPackageJson = sortObjectKeys(packageJson);
185
235
  yield fs.writeFile(
186
236
  path.join(targetDir, "package.json"),
187
- JSON.stringify(packageJson, null, 2)
237
+ `${JSON.stringify(sortedPackageJson, null, 2)}
238
+ `
188
239
  );
189
240
  });
190
241
  }
242
+ function sortObjectKeys(obj) {
243
+ const keyOrder = [
244
+ "name",
245
+ "type",
246
+ "version",
247
+ "description",
248
+ "license",
249
+ "publishConfig",
250
+ "sideEffects",
251
+ "exports",
252
+ "main",
253
+ "module",
254
+ "types",
255
+ "files",
256
+ "scripts",
257
+ "peerDependencies",
258
+ "dependencies",
259
+ "devDependencies"
260
+ ];
261
+ const sortedObj = {};
262
+ for (const key of keyOrder) {
263
+ if (key in obj)
264
+ sortedObj[key] = obj[key];
265
+ }
266
+ const remainingKeys = Object.keys(obj).filter((key) => !keyOrder.includes(key)).sort();
267
+ for (const key of remainingKeys) {
268
+ sortedObj[key] = obj[key];
269
+ }
270
+ for (const key of Object.keys(sortedObj)) {
271
+ if (typeof sortedObj[key] === "object" && sortedObj[key] !== null && !Array.isArray(sortedObj[key])) {
272
+ if (["dependencies", "devDependencies", "peerDependencies"].includes(key)) {
273
+ sortedObj[key] = sortObjectAlphabetically(sortedObj[key]);
274
+ } else {
275
+ sortedObj[key] = sortObjectKeys(sortedObj[key]);
276
+ }
277
+ }
278
+ }
279
+ return sortedObj;
280
+ }
281
+ function sortObjectAlphabetically(obj) {
282
+ const sortedObj = {};
283
+ const sortedKeys = Object.keys(obj).sort();
284
+ for (const key of sortedKeys) {
285
+ sortedObj[key] = obj[key];
286
+ }
287
+ return sortedObj;
288
+ }
191
289
  function createConfigFiles(targetDir) {
192
290
  return __async(this, null, function* () {
193
291
  try {
@@ -239,17 +337,44 @@ function createSourceFiles(targetDir, pluginName, environment) {
239
337
  const pluginContent = pluginTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName));
240
338
  const fileName = `${pluginName}.tsx`;
241
339
  yield fs.writeFile(path.join(targetDir, "src", fileName), pluginContent);
340
+ yield createPlayground(targetDir, pluginName, environment);
242
341
  } catch (error) {
243
342
  console.error("\u65E0\u6CD5\u8BFB\u53D6\u6A21\u677F\u6587\u4EF6:", error);
244
343
  }
245
344
  });
246
345
  }
346
+ function createPlayground(targetDir, pluginName, environment) {
347
+ return __async(this, null, function* () {
348
+ const playgroundDir = path.join(targetDir, "playground");
349
+ yield fs.ensureDir(playgroundDir);
350
+ try {
351
+ const viteConfigTemplate = yield fs.readFile(path.join(templatesDir, "vite.config.ts.template"), "utf-8");
352
+ const htmlTemplate = yield fs.readFile(path.join(templatesDir, "playground/index.html.template"), "utf-8");
353
+ const tsConfigTemplate = yield fs.readFile(path.join(templatesDir, "playground/tsconfig.json.template"), "utf-8");
354
+ const isReact = environment === "react";
355
+ const mainTemplate = yield fs.readFile(
356
+ path.join(templatesDir, `playground/main.${isReact ? "react" : "jsx"}.template`),
357
+ "utf-8"
358
+ );
359
+ const fileExtension = isReact ? "tsx" : "ts";
360
+ const viteConfigContent = viteConfigTemplate.replace(new RegExp("\\{\\{#if isReact\\}\\}(.*?)\\{\\{\\/if\\}\\}", "gs"), isReact ? "$1" : "");
361
+ const htmlContent = htmlTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName)).replace(/\{\{fileExtension\}\}/g, fileExtension);
362
+ const mainContent = mainTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName));
363
+ yield fs.writeFile(path.join(playgroundDir, "vite.config.ts"), viteConfigContent);
364
+ yield fs.writeFile(path.join(playgroundDir, "index.html"), htmlContent);
365
+ yield fs.writeFile(path.join(playgroundDir, `main.${fileExtension}`), mainContent);
366
+ yield fs.writeFile(path.join(playgroundDir, "tsconfig.json"), tsConfigTemplate);
367
+ } catch (error) {
368
+ console.error("\u8BFB\u53D6 playground \u6A21\u677F\u6587\u4EF6\u5931\u8D25:", error);
369
+ }
370
+ });
371
+ }
247
372
  function createReadme(targetDir, pluginName) {
248
373
  return __async(this, null, function* () {
249
374
  try {
250
375
  const readmeTemplate = yield fs.readFile(path.join(templatesDir, "README.md.template"), "utf-8");
251
376
  const description = `${capitalize(pluginName)} Plugin for Knotx`;
252
- const readmeContent = readmeTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{description\}\}/g, description);
377
+ const readmeContent = readmeTemplate.replace(/\{\{pluginName\}\}/g, pluginName).replace(/\{\{capitalizedPluginName\}\}/g, capitalize(pluginName)).replace(/\{\{description\}\}/g, description);
253
378
  yield fs.writeFile(path.join(targetDir, "README.md"), readmeContent);
254
379
  } catch (error) {
255
380
  console.error("\u65E0\u6CD5\u8BFB\u53D6 README \u6A21\u677F\u6587\u4EF6:", error);
@@ -286,6 +411,67 @@ MIT`;
286
411
  function capitalize(str) {
287
412
  return str.charAt(0).toUpperCase() + str.slice(1);
288
413
  }
414
+ function createGitignore(targetDir) {
415
+ return __async(this, null, function* () {
416
+ try {
417
+ const gitignoreTemplate = yield fs.readFile(path.join(templatesDir, ".gitignore.template"), "utf-8");
418
+ yield fs.writeFile(path.join(targetDir, ".gitignore"), gitignoreTemplate);
419
+ } catch (error) {
420
+ console.error("\u65E0\u6CD5\u8BFB\u53D6 .gitignore \u6A21\u677F\u6587\u4EF6:", error);
421
+ const gitignoreContent = `# \u4F9D\u8D56\u76EE\u5F55
422
+ node_modules
423
+
424
+ # \u6784\u5EFA\u4EA7\u7269
425
+ dist
426
+ build
427
+
428
+ # \u65E5\u5FD7\u6587\u4EF6
429
+ logs
430
+ *.log
431
+ npm-debug.log*
432
+ yarn-debug.log*
433
+ yarn-error.log*
434
+ pnpm-debug.log*
435
+
436
+ # \u73AF\u5883\u53D8\u91CF\u6587\u4EF6
437
+ .env
438
+ .env.local
439
+
440
+ # \u7F16\u8F91\u5668\u76EE\u5F55\u548C\u6587\u4EF6
441
+ .vscode
442
+ .idea
443
+ .DS_Store
444
+
445
+ # \u6D4B\u8BD5\u8986\u76D6\u7387
446
+ coverage
447
+ `;
448
+ yield fs.writeFile(path.join(targetDir, ".gitignore"), gitignoreContent);
449
+ }
450
+ });
451
+ }
452
+ function initGitRepo(targetDir) {
453
+ try {
454
+ execSync("git init", { cwd: targetDir, stdio: "ignore" });
455
+ execSync("git add .", { cwd: targetDir, stdio: "ignore" });
456
+ execSync('git commit -m "Initial commit with Knotx plugin template"', {
457
+ cwd: targetDir,
458
+ stdio: "ignore",
459
+ env: __spreadProps(__spreadValues({}, process.env), {
460
+ GIT_AUTHOR_NAME: "Knotx CLI",
461
+ GIT_AUTHOR_EMAIL: "knotx-cli@noreply.github.com",
462
+ GIT_COMMITTER_NAME: "Knotx CLI",
463
+ GIT_COMMITTER_EMAIL: "knotx-cli@noreply.github.com"
464
+ })
465
+ });
466
+ return true;
467
+ } catch (error) {
468
+ if (error instanceof Error) {
469
+ throw new TypeError(`Git \u521D\u59CB\u5316\u5931\u8D25: ${error.message}`);
470
+ } else {
471
+ throw new TypeError(`Git \u521D\u59CB\u5316\u5931\u8D25: ${String(error)}`);
472
+ }
473
+ }
474
+ }
289
475
  program.parse();
290
476
  if (!process.argv.slice(2).length) {
291
477
  program.outputHelp();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knotx/cli",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "CLI tool for Knotx",
5
5
  "author": "boenfu",
6
6
  "license": "MIT",
@@ -11,7 +11,8 @@
11
11
  "directory": "packages/cli"
12
12
  },
13
13
  "publishConfig": {
14
- "access": "public"
14
+ "access": "public",
15
+ "registry": "https://registry.npmjs.org/"
15
16
  },
16
17
  "exports": {
17
18
  ".": {
@@ -40,9 +41,9 @@
40
41
  "devDependencies": {
41
42
  "@types/fs-extra": "^11.0.4",
42
43
  "@types/inquirer": "^9.0.7",
43
- "@knotx/eslint-config": "0.0.1",
44
- "@knotx/typescript-config": "0.0.1",
45
- "@knotx/build-config": "0.0.1"
44
+ "@knotx/build-config": "0.0.3",
45
+ "@knotx/eslint-config": "0.0.3",
46
+ "@knotx/typescript-config": "0.0.3"
46
47
  },
47
48
  "scripts": {
48
49
  "build": "unbuild --failOnWarn=false",
@@ -0,0 +1,45 @@
1
+ # 依赖目录
2
+ node_modules
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # 构建产物
7
+ dist
8
+ build
9
+ *.tsbuildinfo
10
+
11
+ # 日志文件
12
+ logs
13
+ *.log
14
+ npm-debug.log*
15
+ yarn-debug.log*
16
+ yarn-error.log*
17
+ pnpm-debug.log*
18
+
19
+ # 环境变量文件
20
+ .env
21
+ .env.local
22
+ .env.development.local
23
+ .env.test.local
24
+ .env.production.local
25
+
26
+ # 编辑器目录和文件
27
+ .vscode/*
28
+ !.vscode/extensions.json
29
+ !.vscode/settings.json
30
+ .idea
31
+ .DS_Store
32
+ *.suo
33
+ *.ntvs*
34
+ *.njsproj
35
+ *.sln
36
+ *.sw?
37
+
38
+ # 测试覆盖率
39
+ coverage
40
+
41
+ # 缓存
42
+ .eslintcache
43
+ .stylelintcache
44
+ .npm
45
+ .cache
@@ -15,7 +15,7 @@ pnpm add @knotx/plugins-{{pluginName}}
15
15
  ## 使用方法
16
16
 
17
17
  ```typescript
18
- import { {{capitalizedPluginName}} } from '@knotx/plugins-{{pluginName}}';
18
+ import { {{capitalizedPluginName}} } from '@knotx/plugins-{{pluginName}}'
19
19
  ```
20
20
 
21
21
  ## 许可证
@@ -1 +1 @@
1
- export { default } from '@knotx/eslint-config';
1
+ export { default } from '@knotx/eslint-config'
@@ -1 +1 @@
1
- export * from './{{pluginName}}';
1
+ export * from './{{pluginName}}'
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{capitalizedPluginName}} Plugin Playground</title>
7
+ <style>
8
+ body {
9
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
10
+ margin: 0;
11
+ padding: 20px;
12
+ background-color: #f7f7f7;
13
+ }
14
+ .container {
15
+ max-width: 800px;
16
+ margin: 0 auto;
17
+ background-color: white;
18
+ padding: 20px;
19
+ border-radius: 5px;
20
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
21
+ }
22
+ h1 {
23
+ color: #333;
24
+ border-bottom: 1px solid #eee;
25
+ padding-bottom: 10px;
26
+ }
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <div class="container">
31
+ <h1>{{capitalizedPluginName}} Plugin Demo</h1>
32
+ <p>这是 {{pluginName}} 插件的演示页面。您可以在这里测试插件的功能。</p>
33
+
34
+ <div id="app">
35
+ <!-- 插件内容将在这里展示 -->
36
+ </div>
37
+ </div>
38
+
39
+ <script type="module" src="./main.{{fileExtension}}"></script>
40
+ </body>
41
+ </html>
@@ -0,0 +1,11 @@
1
+ import { {{capitalizedPluginName}} } from '../src'
2
+
3
+ // 在这里初始化和使用您的插件
4
+ const plugin = new {{capitalizedPluginName}}()
5
+ plugin.init()
6
+
7
+ // 更新演示区域
8
+ const appElement = document.getElementById('app')
9
+ if (appElement) {
10
+ appElement.innerHTML += '<p>插件已初始化,请查看控制台输出</p>'
11
+ }
@@ -0,0 +1,39 @@
1
+ import { BaseRender } from '@knotx/plugins-base-render'
2
+ import { Knotx } from '@knotx/react'
3
+ import { StrictMode } from 'react'
4
+ import ReactDOM from 'react-dom'
5
+
6
+ import { {{capitalizedPluginName}} } from '../src'
7
+
8
+ function App() {
9
+ const nodes = [
10
+ {
11
+ id: '1',
12
+ position: { x: 0, y: 0 },
13
+ data: {},
14
+ },
15
+ {
16
+ id: '2',
17
+ position: { x: 100, y: 100 },
18
+ data: {},
19
+ },
20
+ ]
21
+ const edges = [
22
+ {
23
+ id: '1',
24
+ source: '1',
25
+ target: '2',
26
+ },
27
+ ]
28
+
29
+ return (
30
+ <Knotx
31
+ style={{ height: 480, boxShadow: '0 0 2px #333', borderRadius: 4 }}
32
+ nodes={nodes}
33
+ edges={edges}
34
+ plugins={[BaseRender, {{capitalizedPluginName}}]}
35
+ />
36
+ )
37
+ }
38
+
39
+ ReactDOM.render(<StrictMode><App /></StrictMode>, document.getElementById('app'))
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "jsx": "react",
5
+ "types": ["vite/client"]
6
+ },
7
+ "include": ["."]
8
+ }
@@ -1,7 +1,7 @@
1
1
  import type { NodeData } from '@knotx/core'
2
2
 
3
- import { inject, OnInit } from '@knotx/decorators'
4
3
  import { BasePlugin } from '@knotx/core'
4
+ import { inject, OnInit } from '@knotx/decorators'
5
5
 
6
6
  export class {{capitalizedPluginName}} extends BasePlugin<'{{pluginName}}'> {
7
7
  name = '{{pluginName}}' as const
@@ -0,0 +1,19 @@
1
+ {{#if isReact}}import react from '@vitejs/plugin-react'{{/if}}
2
+ import { defineConfig } from 'vite'
3
+
4
+ export default defineConfig({
5
+ plugins: [{{#if isReact}}react({
6
+ babel: {
7
+ plugins: [[
8
+ '@babel/plugin-proposal-decorators',
9
+ {
10
+ version: '2023-11',
11
+ decoratorsBeforeExport: true,
12
+ },
13
+ ]],
14
+ },
15
+ }){{/if}}],
16
+ server: {
17
+ port: 5173,
18
+ },
19
+ })