create-blocklet 0.4.49 → 0.4.51

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 (69) hide show
  1. package/index.js +263 -231
  2. package/lib/utils.js +31 -2
  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/{common/_eslintrc.js → templates/monorepo/eslintrc.js} +0 -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 +46 -0
  40. package/templates/monorepo/version +1 -0
  41. package/templates/nextjs-dapp/package.json +9 -7
  42. package/templates/react-dapp/.eslintrc.js +7 -0
  43. package/templates/react-dapp/api/index.js +1 -1
  44. package/templates/react-dapp/package.json +11 -9
  45. package/templates/react-gun-dapp/.eslintrc.js +7 -0
  46. package/templates/react-gun-dapp/api/index.js +1 -1
  47. package/templates/react-gun-dapp/package.json +11 -9
  48. package/templates/react-static/.eslintrc.js +7 -0
  49. package/templates/react-static/package.json +4 -2
  50. package/templates/solidjs-dapp/api/index.js +1 -1
  51. package/templates/solidjs-dapp/blocklet.yml +1 -1
  52. package/templates/solidjs-dapp/package.json +14 -12
  53. package/templates/solidjs-dapp/vite.config.js +1 -1
  54. package/templates/solidjs-static/package.json +7 -5
  55. package/templates/solidjs-static/vite.config.js +1 -1
  56. package/templates/svelte-dapp/api/index.js +1 -1
  57. package/templates/svelte-dapp/blocklet.yml +1 -1
  58. package/templates/svelte-dapp/package.json +12 -10
  59. package/templates/svelte-dapp/vite.config.js +1 -1
  60. package/templates/svelte-static/package.json +6 -4
  61. package/templates/svelte-static/vite.config.js +1 -1
  62. package/templates/vue-dapp/api/index.js +1 -1
  63. package/templates/vue-dapp/package.json +15 -13
  64. package/templates/vue-dapp/vite.config.js +1 -1
  65. package/templates/vue-static/package.json +8 -6
  66. package/templates/vue-static/vite.config.js +1 -1
  67. package/templates/vue2-dapp/api/index.js +1 -1
  68. package/templates/vue2-dapp/package.json +14 -12
  69. 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,111 +32,91 @@ 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
 
127
118
  const renameFiles = {
128
119
  _gitignore: '.gitignore',
129
- '_eslintrc.js': '.eslintrc.js',
130
- _eslintignore: '.eslintignore',
131
120
  _npmrc: '.npmrc',
132
121
  _editorconfig: '.editorconfig',
133
122
  _prettierrc: '.prettierrc',
@@ -135,7 +124,6 @@ const renameFiles = {
135
124
 
136
125
  async function init() {
137
126
  const { version } = await fs.readJSONSync(path.resolve(__dirname, 'package.json'));
138
-
139
127
  await echoBrand({ version });
140
128
 
141
129
  let targetDir = argv._[0] ? String(argv._[0]) : undefined;
@@ -182,39 +170,36 @@ async function init() {
182
170
  validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name',
183
171
  },
184
172
  {
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
- };
173
+ type: 'autocompleteMultiselect',
174
+ name: 'templateNames',
175
+ message: 'Choose one or more blocklet templates:',
176
+ choices: templates.map((template) => {
177
+ const templateColor = template.color;
195
178
  return {
196
- title: TYPE_TITLE[type.name],
197
- value: type.name,
179
+ title: templateColor(template.display),
180
+ value: template.name,
198
181
  };
199
182
  }),
183
+ min: 1,
184
+ suggest: (input, choices) => Promise.resolve(choices.filter((i) => i.title.includes(input))),
200
185
  },
186
+ // 这里需要添加一步 如果选择了 多项 就要提示用户设置主应用
201
187
  {
202
- type: (typeName) => {
203
- const type = TYPES.find((item) => item.name === typeName);
204
- return type && type.frameworks ? 'select' : null;
188
+ type: (templateNames = []) => {
189
+ return templateNames.length > 1 ? 'select' : null;
205
190
  },
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;
191
+ name: 'mainBlocklet',
192
+ message: 'Please choose the main blocklet',
193
+ //
194
+ choices: (templateNames = []) =>
195
+ templateNames.map((templateName) => {
196
+ const template = templates.find((x) => x.name === templateName);
212
197
  return {
213
- title: frameworkColor(framework.display),
214
- value: framework.name,
198
+ title: template.display,
199
+ value: template.name,
215
200
  };
216
- });
217
- },
201
+ }),
202
+ initial: 1,
218
203
  },
219
204
  {
220
205
  type: 'text',
@@ -243,7 +228,7 @@ async function init() {
243
228
  }
244
229
 
245
230
  // user choice associated with prompts
246
- const { type, framework, overwrite, packageName, authorName, authorEmail } = result;
231
+ const { mainBlocklet = null, templateNames = [], overwrite, packageName, authorName, authorEmail } = result;
247
232
 
248
233
  await echoDocument();
249
234
 
@@ -267,96 +252,140 @@ async function init() {
267
252
  console.log(`\nScaffolding project in ${cyan(root)}`);
268
253
 
269
254
  const scaffoldSpinner = ora('Creating project...').start();
270
-
271
- const templateDir = path.join(__dirname, `templates/${framework}-${type}`);
255
+ // name 是用户输入的项目名称,当有
272
256
  const name = packageName || targetDir;
273
257
 
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;
258
+ // 如果选中了多个则说明时 monorepo 类型的模板
259
+ if (mainBlocklet) {
260
+ await checkLerna();
261
+ await checkYarn();
262
+ copy(path.join(__dirname, 'templates', 'monorepo'), root);
263
+ }
264
+
265
+ for (const templateName of templateNames) {
266
+ const templateDir = path.join(__dirname, `templates/${templateName}`);
267
+ const finalTemplateName = `${name}-${templateName}`;
268
+ // TODO: 需要把 common file copy 的逻辑移除,不同的 template 之间的差异越来越多,就会需要越来越多特殊处理的代码,违背了初衷,移除这部分逻辑可能是更好的选择
269
+ // copy common files
270
+ (() => {
271
+ const commonDir = path.join(__dirname, 'common');
272
+ const commonFiles = fs.readdirSync(commonDir);
273
+ for (const file of commonFiles) {
274
+ // 如果选择多个模板,每个子 package 中 只会包含必要的 文件
275
+ if (mainBlocklet && !['screenshots', 'public', 'logo.png', '_prettierrc'].includes(file)) {
276
+ continue;
277
+ }
278
+ // xmark 相关的模板不添加 .husky
279
+ if (fuzzyQuery(['blocklet-page', 'doc-site'], templateName) && ['.husky'].includes(file)) {
280
+ // eslint-disable-next-line no-continue
281
+ continue;
282
+ }
283
+ const targetPath = renameFiles[file]
284
+ ? path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', renameFiles[file])
285
+ : path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', file);
286
+
287
+ copy(path.join(commonDir, file), targetPath);
287
288
  }
288
- const targetPath = renameFiles[file] ? path.join(root, renameFiles[file]) : path.join(root, file);
289
- copy(path.join(commonDir, file), targetPath);
290
- }
291
- })();
289
+ })();
292
290
 
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;
291
+ // copy template files
292
+ (() => {
293
+ const files = fs.readdirSync(templateDir);
294
+ for (const file of files) {
295
+ write(file, null, templateDir, templateName);
328
296
  }
297
+ })();
298
+
299
+ modifyPackage(
300
+ (pkg) => {
301
+ pkg.name = mainBlocklet ? finalTemplateName : name;
302
+ },
303
+ templateDir,
304
+ templateName
305
+ );
306
+ modifyBlockletYaml(
307
+ (yamlConfig) => {
308
+ yamlConfig.name = mainBlocklet ? finalTemplateName : name;
309
+ yamlConfig.title = mainBlocklet ? templateName : name;
310
+ },
311
+ templateDir,
312
+ templateName
313
+ );
314
+
315
+ let randomPort;
316
+ if (fuzzyQuery(['dapp'], templateName)) {
317
+ randomPort = await getPort();
329
318
  }
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 });
319
+ modifyEnv(
320
+ (env) => {
321
+ if (randomPort) {
322
+ env.API_PORT = randomPort;
351
323
  }
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
- })();
324
+ if (!fuzzyQuery(['blocklet-page'], templateName)) {
325
+ if (fuzzyQuery(['react'], templateName)) {
326
+ env.REACT_APP_TITLE = finalTemplateName;
327
+ } else if (fuzzyQuery(['vue', 'blocklet-page'], templateName)) {
328
+ env.VITE_APP_TITLE = finalTemplateName;
329
+ } else {
330
+ env.APP_TITLE = finalTemplateName;
331
+ }
332
+ }
333
+ return env;
334
+ },
335
+ templateDir,
336
+ templateName
337
+ );
338
+
339
+ // patch blocklet author
340
+ modifyBlockletYaml(
341
+ async (yamlConfig) => {
342
+ yamlConfig.author.name = authorName;
343
+ yamlConfig.author.email = authorEmail;
344
+ },
345
+ templateDir,
346
+ templateName
347
+ );
348
+
349
+ // patch did
350
+ (() => {
351
+ const did = toBlockletDid(finalTemplateName);
352
+ modifyBlockletYaml(
353
+ (yamlConfig) => {
354
+ yamlConfig.did = did;
355
+ },
356
+ templateDir,
357
+ templateName
358
+ );
359
+ modifyPackage(
360
+ (pkg) => {
361
+ try {
362
+ if (templateName.includes('dapp')) {
363
+ pkg.scripts['bundle:client'] = ejs.render(pkg.scripts['bundle:client'], { did });
364
+ } else if (templateName.includes('static')) {
365
+ pkg.scripts.bundle = ejs.render(pkg.scripts.bundle, { did });
366
+ }
367
+ // 如果用户选了多个模板,为其他应用配置好 dev:child 和 deploy:child
368
+ if (mainBlocklet && templateName !== mainBlocklet) {
369
+ const mainBlockletDid = toBlockletDid(`${name}-${mainBlocklet}`);
370
+ pkg.scripts['dev:child'] = ejs.render(pkg.scripts['dev:child'], { did: mainBlockletDid });
371
+ pkg.scripts['deploy:child'] = ejs.render(pkg.scripts['deploy:child'], { did: mainBlockletDid });
372
+ }
373
+ if (!mainBlocklet || templateName === mainBlocklet) {
374
+ delete pkg.scripts['dev:child'];
375
+ delete pkg.scripts['deploy:child'];
376
+ }
377
+ } catch {
378
+ console.info('\nNo need to patch bundle script\n');
379
+ }
380
+ },
381
+ templateDir,
382
+ templateName
383
+ );
384
+ // disabled random logo
385
+ // const pngIcon = toDidIcon(did, undefined, true);
386
+ // fs.writeFileSync(path.join(root, 'logo.png'), pngIcon);
387
+ })();
388
+ }
360
389
 
361
390
  scaffoldSpinner.succeed('✨ Done. Now run:\n');
362
391
 
@@ -390,14 +419,15 @@ async function init() {
390
419
 
391
420
  let defaultAgent = 'npm';
392
421
  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
- }
422
+
423
+ // switch (templateNames) {
424
+ // case 'react':
425
+ // case 'blocklet-page':
426
+ // agentList = ['npm', 'yarn'];
427
+ // break;
428
+ // default:
429
+ // break;
430
+ // }
401
431
  if (yes) {
402
432
  const { agent } = await prompts({
403
433
  name: 'agent',
@@ -465,9 +495,13 @@ async function init() {
465
495
  if (!hasStart) {
466
496
  // console.log(dim('\n start it later by:\n'));
467
497
  if (root !== cwd) console.log(blue(` cd ${bold(related)}`));
498
+ if (mainBlocklet) {
499
+ console.log(blue(`make init`));
500
+ } else {
501
+ console.log(blue(`${defaultAgent === 'yarn' ? 'yarn' : `${defaultAgent} install`}`));
502
+ console.log(cyan('blocklet dev'));
503
+ }
468
504
 
469
- console.log(blue(` ${defaultAgent === 'yarn' ? 'yarn' : `${defaultAgent} install`}`));
470
- console.log(cyan('blocklet dev'));
471
505
  console.log('\n', `Find more usage in ${green('README.md')}`, '\n');
472
506
  }
473
507
  } catch (cancelled) {
@@ -475,45 +509,43 @@ async function init() {
475
509
  }
476
510
 
477
511
  // inside functions
478
- function write(file, content) {
479
- const targetPath = renameFiles[file] ? path.join(root, renameFiles[file]) : path.join(root, file);
512
+ function write(file, content, templateDir, templateName) {
513
+ const targetPath = renameFiles[file]
514
+ ? path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', renameFiles[file])
515
+ : path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', file);
480
516
  if (content) {
481
517
  fs.writeFileSync(targetPath, content);
482
518
  } else {
483
519
  copy(path.join(templateDir, file), targetPath);
484
520
  }
485
521
  }
486
- function read(file) {
487
- const targetPath = path.join(root, file);
522
+ function read(file, templateName) {
523
+ const targetPath = path.join(root, mainBlocklet ? `blocklets/${templateName}` : '', file);
488
524
  if (fs.existsSync(targetPath)) {
489
525
  return fs.readFileSync(targetPath, 'utf8');
490
526
  }
491
527
  return null;
492
528
  }
493
529
 
494
- function modifyPackage(modifyFn = () => {}) {
495
- const pkg = JSON.parse(read('package.json'));
530
+ function modifyPackage(modifyFn = () => {}, templateDir, templateName) {
531
+ const pkg = JSON.parse(read('package.json', templateName));
496
532
  modifyFn(pkg);
497
- write('package.json', JSON.stringify(pkg, null, 2));
533
+ write('package.json', JSON.stringify(pkg, null, 2), templateDir, templateName);
498
534
  }
499
535
 
500
- function modifyBlockletYaml(modifyFn = () => {}) {
501
- const blockletYaml = read('blocklet.yml');
536
+ function modifyBlockletYaml(modifyFn = () => {}, templateDir, templateName) {
537
+ const blockletYaml = read('blocklet.yml', templateName);
502
538
  const yamlConfig = YAML.parse(blockletYaml);
503
539
  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);
540
+ write('blocklet.yml', YAML.stringify(yamlConfig, 2), templateDir, templateName);
510
541
  }
511
- function modifyEnv(modifyFn = (...args) => ({ ...args })) {
512
- const envContent = read('.env');
542
+
543
+ function modifyEnv(modifyFn = (...args) => ({ ...args }), templateDir, templateName) {
544
+ const envContent = read('.env', templateName);
513
545
  if (envContent) {
514
546
  const env = envfile.parse(envContent);
515
547
  modifyFn(env);
516
- write('.env', envfile.stringify(env));
548
+ write('.env', envfile.stringify(env), templateDir, templateName);
517
549
  }
518
550
  // else {
519
551
  // 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) {
@@ -6,7 +7,7 @@ export function copy(src, dest) {
6
7
  if (stat.isDirectory()) {
7
8
  copyDir(src, dest);
8
9
  } else {
9
- fs.copyFileSync(src, dest);
10
+ fs.copySync(src, dest);
10
11
  }
11
12
  }
12
13
 
@@ -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.51",
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
  }