create-blocklet 0.4.49 → 0.4.50

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.
Files changed (58) hide show
  1. package/index.js +269 -229
  2. package/lib/utils.js +30 -1
  3. package/package.json +7 -7
  4. package/templates/{blocklet-page-static → blocklet-page}/.blocklet-pages/config.yml +0 -0
  5. package/templates/{blocklet-page-static → blocklet-page}/.blocklet-pages/layouts/MyLayout.mdx +0 -0
  6. package/templates/{blocklet-page-static → blocklet-page}/.blocklet-pages/layouts/images/logo.png +0 -0
  7. package/templates/{blocklet-page-static → blocklet-page}/README.md +0 -0
  8. package/templates/{blocklet-page-static → blocklet-page}/blocklet.md +0 -0
  9. package/templates/{blocklet-page-static → blocklet-page}/blocklet.yml +0 -0
  10. package/templates/{blocklet-page-static → blocklet-page}/package.json +6 -3
  11. package/templates/{blocklet-page-static → blocklet-page}/pages/index.mdx +0 -0
  12. package/templates/{blocklet-page-static → blocklet-page}/pages/index.zh.mdx +0 -0
  13. package/templates/{doc-site-static → doc-site}/.blocklet-pages/config.yml +0 -0
  14. package/templates/{doc-site-static → doc-site}/.blocklet-pages/layouts/Documentation.mdx +0 -0
  15. package/templates/{doc-site-static → doc-site}/.blocklet-pages/layouts/images/logo.png +0 -0
  16. package/templates/{doc-site-static → doc-site}/README.md +0 -0
  17. package/templates/{doc-site-static → doc-site}/blocklet.md +0 -0
  18. package/templates/{doc-site-static → doc-site}/blocklet.yml +0 -0
  19. package/templates/{doc-site-static → doc-site}/package.json +7 -4
  20. package/templates/{doc-site-static → doc-site}/pages/index.mdx +0 -0
  21. package/templates/{doc-site-static → doc-site}/pages/index.zh.mdx +0 -0
  22. package/templates/{doc-site-static → doc-site}/pages/intro/index.mdx +0 -0
  23. package/templates/{doc-site-static → doc-site}/pages/intro/index.zh.mdx +0 -0
  24. package/templates/express-api/.env +1 -0
  25. package/templates/express-api/package.json +7 -5
  26. package/templates/html-static/package.json +3 -0
  27. package/templates/monorepo/.editorconfig +23 -0
  28. package/templates/monorepo/.github/workflows/main.yml +36 -0
  29. package/templates/monorepo/.github/workflows/pr-title.yml +21 -0
  30. package/templates/monorepo/.github/workflows/version-check.yml +20 -0
  31. package/templates/monorepo/.husky/pre-commit +4 -0
  32. package/templates/monorepo/.prettierrc +9 -0
  33. package/templates/monorepo/LICENSE +13 -0
  34. package/templates/monorepo/Makefile +22 -0
  35. package/templates/monorepo/README.md +64 -0
  36. package/templates/monorepo/eslintrc.js +7 -0
  37. package/templates/monorepo/lerna.json +14 -0
  38. package/templates/monorepo/package.json +31 -0
  39. package/templates/monorepo/scripts/bump-version.mjs +32 -0
  40. package/templates/monorepo/version +1 -0
  41. package/templates/nextjs-dapp/package.json +9 -7
  42. package/templates/react-dapp/api/index.js +1 -1
  43. package/templates/react-dapp/package.json +11 -9
  44. package/templates/react-gun-dapp/api/index.js +1 -1
  45. package/templates/react-gun-dapp/package.json +11 -9
  46. package/templates/react-static/package.json +4 -2
  47. package/templates/solidjs-dapp/api/index.js +1 -1
  48. package/templates/solidjs-dapp/package.json +14 -12
  49. package/templates/solidjs-static/package.json +7 -5
  50. package/templates/svelte-dapp/api/index.js +1 -1
  51. package/templates/svelte-dapp/package.json +12 -10
  52. package/templates/svelte-static/package.json +6 -4
  53. package/templates/vue-dapp/api/index.js +1 -1
  54. package/templates/vue-dapp/package.json +15 -13
  55. package/templates/vue-static/package.json +8 -6
  56. package/templates/vue2-dapp/api/index.js +1 -1
  57. package/templates/vue2-dapp/package.json +14 -12
  58. package/templates/vue2-static/package.json +7 -5
package/index.js CHANGED
@@ -15,7 +15,16 @@ import { getUser } from './lib/index.js';
15
15
  import { checkServerInstalled, checkServerRunning, checkSatisfiedVersion, getServerDirectory } from './lib/server.js';
16
16
  import { toBlockletDid } from './lib/did.js';
17
17
  import { initGitRepo } from './lib/git.js';
18
- import { copy, emptyDir, isEmpty, isValidPackageName, toValidPackageName } from './lib/utils.js';
18
+ import {
19
+ copy,
20
+ emptyDir,
21
+ isEmpty,
22
+ isValidPackageName,
23
+ toValidPackageName,
24
+ fuzzyQuery,
25
+ checkLerna,
26
+ checkYarn,
27
+ } from './lib/utils.js';
19
28
 
20
29
  const { yellow, red, green, cyan, blue, bold, magenta } = chalk;
21
30
 
@@ -23,104 +32,86 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
23
32
 
24
33
  const cwd = process.cwd();
25
34
 
26
- const TYPES = [
35
+ const templates = [
27
36
  {
28
- name: 'dapp',
37
+ name: 'react-dapp',
38
+ display: '[dapp] react + express.js',
29
39
  color: yellow,
30
- frameworks: [
31
- {
32
- name: 'react',
33
- display: 'react',
34
- color: yellow,
35
- },
36
- {
37
- name: 'solidjs',
38
- display: 'solidjs',
39
- color: yellow,
40
- },
41
- {
42
- name: 'vue',
43
- display: 'vue3 + vite',
44
- color: green,
45
- },
46
- {
47
- name: 'vue2',
48
- display: 'vue2 + @vue/cli',
49
- color: green,
50
- },
51
- {
52
- name: 'svelte',
53
- display: 'svelte',
54
- color: magenta,
55
- },
56
- {
57
- name: 'nextjs',
58
- display: 'next.js',
59
- color: blue,
60
- },
61
- {
62
- name: 'react-gun',
63
- display: 'react + gunjs',
64
- color: blue,
65
- },
66
- ],
67
40
  },
68
41
  {
69
- name: 'static',
42
+ name: 'solidjs-dapp',
43
+ display: '[dapp] solid + express.js',
70
44
  color: yellow,
71
- frameworks: [
72
- {
73
- name: 'react',
74
- display: 'react',
75
- color: yellow,
76
- },
77
- {
78
- name: 'solidjs',
79
- display: 'solidjs',
80
- color: yellow,
81
- },
82
- {
83
- name: 'vue',
84
- display: 'vue3 + vite',
85
- color: green,
86
- },
87
- {
88
- name: 'vue2',
89
- display: 'vue2 + @vue/cli',
90
- color: green,
91
- },
92
- {
93
- name: 'svelte',
94
- display: 'svelte',
95
- color: magenta,
96
- },
97
- {
98
- name: 'blocklet-page',
99
- display: 'blocklet page',
100
- color: blue,
101
- },
102
- {
103
- name: 'doc-site',
104
- display: 'doc site',
105
- color: blue,
106
- },
107
- {
108
- name: 'html',
109
- display: 'html',
110
- color: blue,
111
- },
112
- ],
113
45
  },
114
46
  {
115
- name: 'api',
47
+ name: 'vue-dapp',
48
+ display: '[dapp] vue3 + express.js',
49
+ color: green,
50
+ },
51
+ {
52
+ name: 'vue2-dapp',
53
+ display: '[dapp] vue2 + express.js',
54
+ color: green,
55
+ },
56
+ {
57
+ name: 'svelte-dapp',
58
+ display: '[dapp] svelte + express.js',
59
+ color: magenta,
60
+ },
61
+ {
62
+ name: 'nextjs-dapp',
63
+ display: '[dapp] next.js',
64
+ color: blue,
65
+ },
66
+ {
67
+ name: 'react-gun-dapp',
68
+ display: '[dapp] react + gun.js + express.js',
69
+ color: blue,
70
+ },
71
+ {
72
+ name: 'react-static',
73
+ display: '[static] react',
74
+ color: yellow,
75
+ },
76
+ {
77
+ name: 'solidjs-static',
78
+ display: '[static] solidjs',
79
+ color: yellow,
80
+ },
81
+ {
82
+ name: 'vue-static',
83
+ display: '[static] vue3 + vite',
84
+ color: green,
85
+ },
86
+ {
87
+ name: 'vue2-static',
88
+ display: '[static] vue2 + @vue/cli',
89
+ color: green,
90
+ },
91
+ {
92
+ name: 'svelte-static',
93
+ display: '[static] svelte',
94
+ color: magenta,
95
+ },
96
+ {
97
+ name: 'blocklet-page',
98
+ display: '[static] blocklet page',
99
+ color: blue,
100
+ },
101
+ {
102
+ name: 'doc-site',
103
+ display: '[static] doc site',
104
+ color: blue,
105
+ },
106
+ {
107
+ name: 'html-static',
108
+ display: '[static] html',
109
+ color: blue,
110
+ },
111
+ {
112
+ name: 'express-api',
113
+ display: '[api] express.js',
116
114
  color: yellow,
117
- frameworks: [
118
- {
119
- name: 'express',
120
- display: 'express',
121
- color: yellow,
122
- },
123
- ],
124
115
  },
125
116
  ];
126
117
 
@@ -135,7 +126,6 @@ const renameFiles = {
135
126
 
136
127
  async function init() {
137
128
  const { version } = await fs.readJSONSync(path.resolve(__dirname, 'package.json'));
138
-
139
129
  await echoBrand({ version });
140
130
 
141
131
  let targetDir = argv._[0] ? String(argv._[0]) : undefined;
@@ -182,39 +172,36 @@ async function init() {
182
172
  validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name',
183
173
  },
184
174
  {
185
- type: 'select',
186
- name: 'type',
187
- message: 'What type blocklet you want to create:',
188
- initial: 0,
189
- choices: TYPES.map((type) => {
190
- const TYPE_TITLE = {
191
- dapp: 'fullstack: webapp with backend code',
192
- static: 'webapp: browser only',
193
- api: 'api: backend only',
194
- };
175
+ type: 'autocompleteMultiselect',
176
+ name: 'templateNames',
177
+ message: 'Choose one or more blocklet templates:',
178
+ choices: templates.map((template) => {
179
+ const templateColor = template.color;
195
180
  return {
196
- title: TYPE_TITLE[type.name],
197
- value: type.name,
181
+ title: templateColor(template.display),
182
+ value: template.name,
198
183
  };
199
184
  }),
185
+ min: 1,
186
+ suggest: (input, choices) => Promise.resolve(choices.filter((i) => i.title.includes(input))),
200
187
  },
188
+ // 这里需要添加一步 如果选择了 多项 就要提示用户设置主应用
201
189
  {
202
- type: (typeName) => {
203
- const type = TYPES.find((item) => item.name === typeName);
204
- return type && type.frameworks ? 'select' : null;
190
+ type: (templateNames = []) => {
191
+ return templateNames.length > 1 ? 'select' : null;
205
192
  },
206
- name: 'framework',
207
- message: 'Select a framework:',
208
- choices: (typeName) => {
209
- const type = TYPES.find((item) => item.name === typeName);
210
- return type.frameworks.map((framework) => {
211
- const frameworkColor = framework.color;
193
+ name: 'mainBlocklet',
194
+ message: 'Please choose the main blocklet',
195
+ //
196
+ choices: (templateNames = []) =>
197
+ templateNames.map((templateName) => {
198
+ const template = templates.find((x) => x.name === templateName);
212
199
  return {
213
- title: frameworkColor(framework.display),
214
- value: framework.name,
200
+ title: template.display,
201
+ value: template.name,
215
202
  };
216
- });
217
- },
203
+ }),
204
+ initial: 1,
218
205
  },
219
206
  {
220
207
  type: 'text',
@@ -243,7 +230,7 @@ async function init() {
243
230
  }
244
231
 
245
232
  // user choice associated with prompts
246
- const { type, framework, overwrite, packageName, authorName, authorEmail } = result;
233
+ const { mainBlocklet = null, templateNames = [], overwrite, packageName, authorName, authorEmail } = result;
247
234
 
248
235
  await echoDocument();
249
236
 
@@ -267,96 +254,146 @@ async function init() {
267
254
  console.log(`\nScaffolding project in ${cyan(root)}`);
268
255
 
269
256
  const scaffoldSpinner = ora('Creating project...').start();
270
-
271
- const templateDir = path.join(__dirname, `templates/${framework}-${type}`);
257
+ // name 是用户输入的项目名称,当有
272
258
  const name = packageName || targetDir;
273
259
 
274
- // TODO: 需要把 common file copy 的逻辑移除,不同的 template 之间的差异越来越多,就会需要越来越多特殊处理的代码,违背了初衷,移除这部分逻辑可能是更好的选择
275
- // copy common files
276
- (() => {
277
- const commonDir = path.join(__dirname, 'common');
278
- const commonFiles = fs.readdirSync(commonDir);
279
- for (const file of commonFiles) {
280
- if (!['react', 'react-gun',].includes(framework) && file === '_eslintrc.js') {
281
- // eslint-disable-next-line no-continue
282
- continue;
283
- }
284
- if (['blocklet-page','doc-site'].includes(framework) && ['_eslintignore', '.husky'].includes(file)) {
285
- // eslint-disable-next-line no-continue
286
- continue;
260
+ // 如果选中了多个则说明时 monorepo 类型的模板
261
+ if (mainBlocklet) {
262
+ await checkLerna();
263
+ await checkYarn();
264
+ copy(path.join(__dirname, 'templates', 'monorepo'), root);
265
+ }
266
+
267
+ for (const templateName of templateNames) {
268
+ const templateDir = path.join(__dirname, `templates/${templateName}`);
269
+ const finalTemplateName = `${name}-${templateName}`;
270
+ // TODO: 需要把 common file copy 的逻辑移除,不同的 template 之间的差异越来越多,就会需要越来越多特殊处理的代码,违背了初衷,移除这部分逻辑可能是更好的选择
271
+ // copy common files
272
+ (() => {
273
+ const commonDir = path.join(__dirname, 'common');
274
+ const commonFiles = fs.readdirSync(commonDir);
275
+ for (const file of commonFiles) {
276
+ // 如果选中了多个模板时,应该排除掉这些
277
+ if (mainBlocklet && ['Makefile', 'version', '_npmrc', '_editorconfig', '_gitignore'].includes(file)) {
278
+ continue;
279
+ }
280
+ // react 相关的模板使用通用的 eslintrc.js 文件
281
+ if (!fuzzyQuery(['react', 'react-gun'], templateName) && file === '_eslintrc.js') {
282
+ // eslint-disable-next-line no-continue
283
+ continue;
284
+ }
285
+ // xmark 相关的模板不添加 .eslintignore 和 .includes
286
+ if (fuzzyQuery(['blocklet-page', 'doc-site'], templateName) && ['_eslintignore', '.husky'].includes(file)) {
287
+ // eslint-disable-next-line no-continue
288
+ continue;
289
+ }
290
+ // 如果选中了多个模板,则要将 common file copy 到项目 root 目录下的 blocklets 中
291
+ const targetPath = renameFiles[file]
292
+ ? path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', renameFiles[file])
293
+ : path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', file);
294
+
295
+ copy(path.join(commonDir, file), targetPath);
287
296
  }
288
- const targetPath = renameFiles[file] ? path.join(root, renameFiles[file]) : path.join(root, file);
289
- copy(path.join(commonDir, file), targetPath);
290
- }
291
- })();
297
+ })();
292
298
 
293
- // copy template files
294
- (() => {
295
- const files = fs.readdirSync(templateDir);
296
- for (const file of files) {
297
- write(file);
298
- }
299
- })();
300
-
301
- // correctName
302
- modifyPackage((pkg) => {
303
- pkg.name = name;
304
- });
305
- modifyBlockletYaml((yamlConfig) => {
306
- yamlConfig.name = name;
307
- yamlConfig.title = name;
308
- });
309
- modifyBlockletMd((md) => {
310
- return md.replace(/# template-react/g, `# ${name}`);
311
- });
312
-
313
- let randomPort;
314
- if (['dapp'].includes(type)) {
315
- randomPort = await getPort();
316
- }
317
- modifyEnv((env) => {
318
- if (randomPort) {
319
- env.API_PORT = randomPort;
320
- }
321
- if (!['blocklet-page'].includes(framework)) {
322
- if (['react'].includes(framework)) {
323
- env.REACT_APP_TITLE = name;
324
- } else if (['vue', 'blocklet-page'].includes(framework)) {
325
- env.VITE_APP_TITLE = name;
326
- } else {
327
- env.APP_TITLE = name;
299
+ // copy template files
300
+ (() => {
301
+ const files = fs.readdirSync(templateDir);
302
+ for (const file of files) {
303
+ write(file, null, templateDir, templateName);
328
304
  }
305
+ })();
306
+
307
+ modifyPackage(
308
+ (pkg) => {
309
+ pkg.name = finalTemplateName;
310
+ },
311
+ templateDir,
312
+ templateName
313
+ );
314
+ modifyBlockletYaml(
315
+ (yamlConfig) => {
316
+ yamlConfig.name = finalTemplateName;
317
+ yamlConfig.title = finalTemplateName;
318
+ },
319
+ templateDir,
320
+ templateName
321
+ );
322
+
323
+ let randomPort;
324
+ if (fuzzyQuery(['dapp'], templateName)) {
325
+ randomPort = await getPort();
329
326
  }
330
- return env;
331
- });
332
-
333
- // patch blocklet author
334
- modifyBlockletYaml(async (yamlConfig) => {
335
- yamlConfig.author.name = authorName;
336
- yamlConfig.author.email = authorEmail;
337
- });
338
-
339
- // patch did
340
- (() => {
341
- const did = toBlockletDid(name);
342
- modifyBlockletYaml((yamlConfig) => {
343
- yamlConfig.did = did;
344
- });
345
- modifyPackage((pkg) => {
346
- try {
347
- if (type === 'dapp') {
348
- pkg.scripts['bundle:client'] = ejs.render(pkg.scripts['bundle:client'], { did });
349
- } else if (type === 'static') {
350
- pkg.scripts.bundle = ejs.render(pkg.scripts.bundle, { did });
327
+ modifyEnv(
328
+ (env) => {
329
+ if (randomPort) {
330
+ env.API_PORT = randomPort;
351
331
  }
352
- } catch {
353
- console.info('\nNo need to patch bundle script\n');
354
- }
355
- });
356
- // disabled random logo
357
- // const pngIcon = toDidIcon(did, undefined, true);
358
- // fs.writeFileSync(path.join(root, 'logo.png'), pngIcon);
359
- })();
332
+ if (!fuzzyQuery(['blocklet-page'], templateName)) {
333
+ if (fuzzyQuery(['react'], templateName)) {
334
+ env.REACT_APP_TITLE = finalTemplateName;
335
+ } else if (fuzzyQuery(['vue', 'blocklet-page'], templateName)) {
336
+ env.VITE_APP_TITLE = finalTemplateName;
337
+ } else {
338
+ env.APP_TITLE = finalTemplateName;
339
+ }
340
+ }
341
+ return env;
342
+ },
343
+ templateDir,
344
+ templateName
345
+ );
346
+
347
+ // patch blocklet author
348
+ modifyBlockletYaml(
349
+ async (yamlConfig) => {
350
+ yamlConfig.author.name = authorName;
351
+ yamlConfig.author.email = authorEmail;
352
+ },
353
+ templateDir,
354
+ templateName
355
+ );
356
+
357
+ // patch did
358
+ (() => {
359
+ const did = toBlockletDid(finalTemplateName);
360
+ modifyBlockletYaml(
361
+ (yamlConfig) => {
362
+ yamlConfig.did = did;
363
+ },
364
+ templateDir,
365
+ templateName
366
+ );
367
+ modifyPackage(
368
+ (pkg) => {
369
+ try {
370
+ if (templateName.includes('dapp')) {
371
+ pkg.scripts['bundle:client'] = ejs.render(pkg.scripts['bundle:client'], { did });
372
+ } else if (templateName.includes('static')) {
373
+ pkg.scripts.bundle = ejs.render(pkg.scripts.bundle, { did });
374
+ }
375
+ // 如果用户选了多个模板,为其他应用配置好 dev:child 和 deploy:child
376
+ if (mainBlocklet && templateName !== mainBlocklet) {
377
+ const mainBlockletDid = toBlockletDid(`${name}-${mainBlocklet}`);
378
+ pkg.scripts['dev:child'] = ejs.render(pkg.scripts['dev:child'], { did: mainBlockletDid });
379
+ pkg.scripts['deploy:child'] = ejs.render(pkg.scripts['deploy:child'], { did: mainBlockletDid });
380
+ }
381
+ if (!mainBlocklet || templateName === mainBlocklet) {
382
+ delete pkg.scripts['dev:child'];
383
+ delete pkg.scripts['deploy:child'];
384
+ }
385
+ } catch {
386
+ console.info('\nNo need to patch bundle script\n');
387
+ }
388
+ },
389
+ templateDir,
390
+ templateName
391
+ );
392
+ // disabled random logo
393
+ // const pngIcon = toDidIcon(did, undefined, true);
394
+ // fs.writeFileSync(path.join(root, 'logo.png'), pngIcon);
395
+ })();
396
+ }
360
397
 
361
398
  scaffoldSpinner.succeed('✨ Done. Now run:\n');
362
399
 
@@ -390,14 +427,15 @@ async function init() {
390
427
 
391
428
  let defaultAgent = 'npm';
392
429
  let agentList = ['npm', 'yarn', 'pnpm'];
393
- switch (framework) {
394
- case 'react':
395
- case 'blocklet-page':
396
- agentList = ['npm', 'yarn'];
397
- break;
398
- default:
399
- break;
400
- }
430
+
431
+ // switch (templateNames) {
432
+ // case 'react':
433
+ // case 'blocklet-page':
434
+ // agentList = ['npm', 'yarn'];
435
+ // break;
436
+ // default:
437
+ // break;
438
+ // }
401
439
  if (yes) {
402
440
  const { agent } = await prompts({
403
441
  name: 'agent',
@@ -465,9 +503,13 @@ async function init() {
465
503
  if (!hasStart) {
466
504
  // console.log(dim('\n start it later by:\n'));
467
505
  if (root !== cwd) console.log(blue(` cd ${bold(related)}`));
506
+ if (mainBlocklet) {
507
+ console.log(blue(`make init`));
508
+ } else {
509
+ console.log(blue(`${defaultAgent === 'yarn' ? 'yarn' : `${defaultAgent} install`}`));
510
+ console.log(cyan('blocklet dev'));
511
+ }
468
512
 
469
- console.log(blue(` ${defaultAgent === 'yarn' ? 'yarn' : `${defaultAgent} install`}`));
470
- console.log(cyan('blocklet dev'));
471
513
  console.log('\n', `Find more usage in ${green('README.md')}`, '\n');
472
514
  }
473
515
  } catch (cancelled) {
@@ -475,45 +517,43 @@ async function init() {
475
517
  }
476
518
 
477
519
  // inside functions
478
- function write(file, content) {
479
- const targetPath = renameFiles[file] ? path.join(root, renameFiles[file]) : path.join(root, file);
520
+ function write(file, content, templateDir, templateName) {
521
+ const targetPath = renameFiles[file]
522
+ ? path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', renameFiles[file])
523
+ : path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', file);
480
524
  if (content) {
481
525
  fs.writeFileSync(targetPath, content);
482
526
  } else {
483
527
  copy(path.join(templateDir, file), targetPath);
484
528
  }
485
529
  }
486
- function read(file) {
487
- const targetPath = path.join(root, file);
530
+ function read(file, templateName) {
531
+ const targetPath = path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', file);
488
532
  if (fs.existsSync(targetPath)) {
489
533
  return fs.readFileSync(targetPath, 'utf8');
490
534
  }
491
535
  return null;
492
536
  }
493
537
 
494
- function modifyPackage(modifyFn = () => {}) {
495
- const pkg = JSON.parse(read('package.json'));
538
+ function modifyPackage(modifyFn = () => {}, templateDir, templateName) {
539
+ const pkg = JSON.parse(read('package.json', templateName));
496
540
  modifyFn(pkg);
497
- write('package.json', JSON.stringify(pkg, null, 2));
541
+ write('package.json', JSON.stringify(pkg, null, 2), templateDir, templateName);
498
542
  }
499
543
 
500
- function modifyBlockletYaml(modifyFn = () => {}) {
501
- const blockletYaml = read('blocklet.yml');
544
+ function modifyBlockletYaml(modifyFn = () => {}, templateDir, templateName) {
545
+ const blockletYaml = read('blocklet.yml', templateName);
502
546
  const yamlConfig = YAML.parse(blockletYaml);
503
547
  modifyFn(yamlConfig);
504
- write('blocklet.yml', YAML.stringify(yamlConfig, 2));
505
- }
506
- function modifyBlockletMd(modifyFn = (...args) => ({ ...args })) {
507
- const blockletMd = read('blocklet.md', 'utf8');
508
- const modifyMd = modifyFn(blockletMd);
509
- write('blocklet.md', modifyMd);
548
+ write('blocklet.yml', YAML.stringify(yamlConfig, 2), templateDir, templateName);
510
549
  }
511
- function modifyEnv(modifyFn = (...args) => ({ ...args })) {
512
- const envContent = read('.env');
550
+
551
+ function modifyEnv(modifyFn = (...args) => ({ ...args }), templateDir, templateName) {
552
+ const envContent = read('.env', templateName);
513
553
  if (envContent) {
514
554
  const env = envfile.parse(envContent);
515
555
  modifyFn(env);
516
- write('.env', envfile.stringify(env));
556
+ write('.env', envfile.stringify(env), templateDir, templateName);
517
557
  }
518
558
  // else {
519
559
  // console.warn(`\n${yellow('No .env file found, please add one.')}`);
package/lib/utils.js CHANGED
@@ -1,4 +1,5 @@
1
- import { fs, path } from 'zx';
1
+ import { fs, path, $, echo, chalk } from 'zx';
2
+ $.verbose = false;
2
3
 
3
4
  // common functions
4
5
  export function copy(src, dest) {
@@ -51,3 +52,31 @@ export function emptyDir(dir) {
51
52
  }
52
53
  }
53
54
  }
55
+
56
+ export function fuzzyQuery(list = [], keyWord = '') {
57
+ const arr = [];
58
+ for (var i = 0; i < list.length; i++) {
59
+ if (keyWord.includes(list[i])) {
60
+ arr.push(list[i]);
61
+ }
62
+ }
63
+ return arr.length > 0;
64
+ }
65
+
66
+ export async function checkLerna() {
67
+ const checkResult = await $`type lerna >/dev/null 2>&1 || echo "false"`;
68
+ if (checkResult.stdout.trim() === 'false') {
69
+ console.log(`\n ${chalk.cyan('install lerna...')}`);
70
+ const output = await $`npm install -g lerna`;
71
+ echo(output);
72
+ }
73
+ }
74
+
75
+ export async function checkYarn() {
76
+ const checkResult = await $`type yarn >/dev/null 2>&1 || echo "false"`;
77
+ if (checkResult.stdout.trim() === 'false') {
78
+ console.log(`\n ${chalk.cyan('install yarn...')}`);
79
+ const output = await $`npm install -g yarn`;
80
+ echo(output);
81
+ }
82
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-blocklet",
3
- "version": "0.4.49",
3
+ "version": "0.4.50",
4
4
  "exports": "./index.js",
5
5
  "type": "module",
6
6
  "repository": "git@github.com:blocklet/create-blocklet.git",
@@ -29,15 +29,15 @@
29
29
  "test:run": "vitest run"
30
30
  },
31
31
  "dependencies": {
32
- "@arcblock/did": "^1.17.16",
33
- "@ocap/mcrypto": "^1.17.16",
34
- "@ocap/util": "^1.17.16",
32
+ "@arcblock/did": "^1.17.19",
33
+ "@ocap/mcrypto": "^1.17.19",
34
+ "@ocap/util": "^1.17.19",
35
35
  "boxen": "^6.2.1",
36
36
  "ejs": "^3.1.8",
37
- "envfile": "^6.17.0",
37
+ "envfile": "^6.18.0",
38
38
  "figlet": "^1.5.2",
39
39
  "get-port": "^6.1.2",
40
- "gradient-string": "^2.0.1",
40
+ "gradient-string": "^2.0.2",
41
41
  "jdenticon": "^3.2.0",
42
42
  "ora": "^6.1.2",
43
43
  "prompts": "^2.4.2",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "devDependencies": {
49
49
  "@arcblock/eslint-config-base": "0.2.2",
50
- "eslint": "^8.23.0",
50
+ "eslint": "^8.23.1",
51
51
  "prettier": "^2.7.1",
52
52
  "vitest": "^0.19.1"
53
53
  }