create-widget 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.
Files changed (44) hide show
  1. package/lib/index.js +53 -35
  2. package/package.json +7 -4
  3. package/.editorconfig +0 -13
  4. package/.idea/create-widget.iml +0 -9
  5. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  6. package/.idea/jpa-buddy.xml +0 -6
  7. package/.idea/misc.xml +0 -8
  8. package/.idea/modules.xml +0 -8
  9. package/.idea/prettier.xml +0 -6
  10. package/.idea/vcs.xml +0 -6
  11. package/src/index.ts +0 -144
  12. package/src/utils/FileUtils.ts +0 -33
  13. package/src/utils/deepMerge.ts +0 -26
  14. package/src/utils/directoryTraverse.ts +0 -35
  15. package/src/utils/getCommand.ts +0 -13
  16. package/src/utils/renderTemplate.ts +0 -88
  17. package/src/utils/sortDependencies.ts +0 -22
  18. package/test/index.test.ts +0 -24
  19. package/tsconfig.json +0 -12
  20. package/tsup.config.ts +0 -6
  21. package/widget-test/.vscode/extensions.json +0 -3
  22. package/widget-test/README.md +0 -40
  23. package/widget-test/env.d.ts +0 -1
  24. package/widget-test/index.html +0 -13
  25. package/widget-test/package.json +0 -30
  26. package/widget-test/public/favicon.ico +0 -0
  27. package/widget-test/public/preview_clock.png +0 -0
  28. package/widget-test/public/widget.json +0 -50
  29. package/widget-test/src/App.vue +0 -9
  30. package/widget-test/src/assets/main.css +0 -3
  31. package/widget-test/src/main.ts +0 -12
  32. package/widget-test/src/router/index.ts +0 -11
  33. package/widget-test/src/widgets/clock/Clock.widget.ts +0 -32
  34. package/widget-test/src/widgets/clock/ClockConfigView.vue +0 -38
  35. package/widget-test/src/widgets/clock/ClockWidgetRoutes.ts +0 -28
  36. package/widget-test/src/widgets/clock/ClockWidgetView.vue +0 -34
  37. package/widget-test/src/widgets/clock/model/ClockModel.ts +0 -5
  38. package/widget-test/src/widgets/widget-router.ts +0 -8
  39. package/widget-test/tsconfig.app.json +0 -13
  40. package/widget-test/tsconfig.json +0 -11
  41. package/widget-test/tsconfig.node.json +0 -17
  42. package/widget-test/vite.config.ts +0 -14
  43. package/widget-test/widget.package.ts +0 -20
  44. package/widget-test/yarn.lock +0 -1399
package/lib/index.js CHANGED
@@ -1,15 +1,38 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from === "object" || typeof from === "function") {
9
+ for (let key of __getOwnPropNames(from))
10
+ if (!__hasOwnProp.call(to, key) && key !== except)
11
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ }
13
+ return to;
14
+ };
15
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
+ // If the importer is in node compatibility mode or this is not an ESM
17
+ // file that has been converted to a CommonJS file using a Babel-
18
+ // compatible transform (i.e. "__esModule" has not been set), then set
19
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
+ mod
22
+ ));
23
+
1
24
  // src/index.ts
2
- import fs3 from "fs";
3
- import * as process from "process";
4
- import gradient from "gradient-string";
5
- import prompts from "prompts";
6
- import minimist from "minimist";
7
- import chalk from "chalk";
8
- import path2 from "path";
25
+ var import_fs = __toESM(require("fs"));
26
+ var process = __toESM(require("process"));
27
+ var import_gradient_string = __toESM(require("gradient-string"));
28
+ var import_prompts = __toESM(require("prompts"));
29
+ var import_minimist = __toESM(require("minimist"));
30
+ var import_chalk = __toESM(require("chalk"));
31
+ var import_path = __toESM(require("path"));
9
32
 
10
33
  // src/utils/directoryTraverse.ts
11
- import * as fs from "node:fs";
12
- import * as path from "node:path";
34
+ var fs = __toESM(require("fs"));
35
+ var path = __toESM(require("path"));
13
36
  function postOrderDirectoryTraverse(dir, dirCallback, fileCallback) {
14
37
  for (const filename of fs.readdirSync(dir)) {
15
38
  if (filename === ".git") {
@@ -37,16 +60,13 @@ function getCommand(packageManager, scriptName, args) {
37
60
  }
38
61
  }
39
62
 
40
- // src/index.ts
41
- import { fileURLToPath } from "url";
42
-
43
63
  // src/utils/FileUtils.ts
44
- import * as fs2 from "fs";
45
- import { copy, ensureDir } from "fs-extra";
64
+ var fs2 = __toESM(require("fs"));
65
+ var import_fs_extra = require("fs-extra");
46
66
  var FileUtils = class {
47
67
  static async copyFolderRecursive(src, dest) {
48
68
  try {
49
- await ensureDir(dest);
69
+ await (0, import_fs_extra.ensureDir)(dest);
50
70
  const items = await fs2.promises.readdir(src);
51
71
  for (const item of items) {
52
72
  const srcPath = `${src}/${item}`;
@@ -55,7 +75,7 @@ var FileUtils = class {
55
75
  if (stats.isDirectory()) {
56
76
  await this.copyFolderRecursive(srcPath, destPath);
57
77
  } else {
58
- await copy(srcPath, destPath);
78
+ await (0, import_fs_extra.copy)(srcPath, destPath);
59
79
  }
60
80
  }
61
81
  } catch (error) {
@@ -65,13 +85,11 @@ var FileUtils = class {
65
85
  };
66
86
 
67
87
  // src/index.ts
68
- var __filename = fileURLToPath(import.meta.url);
69
- var __dirname = path2.dirname(__filename);
70
88
  function canSkipEmptying(dir) {
71
- if (!fs3.existsSync(dir)) {
89
+ if (!import_fs.default.existsSync(dir)) {
72
90
  return true;
73
91
  }
74
- const files = fs3.readdirSync(dir);
92
+ const files = import_fs.default.readdirSync(dir);
75
93
  if (files.length === 0) {
76
94
  return true;
77
95
  }
@@ -81,26 +99,26 @@ function canSkipEmptying(dir) {
81
99
  return false;
82
100
  }
83
101
  function emptyDir(dir) {
84
- if (!fs3.existsSync(dir)) {
102
+ if (!import_fs.default.existsSync(dir)) {
85
103
  return;
86
104
  }
87
105
  postOrderDirectoryTraverse(
88
106
  dir,
89
- (dir2) => fs3.rmdirSync(dir2),
90
- (file) => fs3.unlinkSync(file)
107
+ (dir2) => import_fs.default.rmdirSync(dir2),
108
+ (file) => import_fs.default.unlinkSync(file)
91
109
  );
92
110
  }
93
111
  async function init() {
94
112
  console.log();
95
113
  let defaultBanner = "Widget.js - The Desktop Widget Framework";
96
- const gradientBanner = gradient([
114
+ const gradientBanner = (0, import_gradient_string.default)([
97
115
  { color: "#42d392", pos: 0 },
98
116
  { color: "#42d392", pos: 0.1 },
99
117
  { color: "#647eff", pos: 1 }
100
118
  ])(defaultBanner);
101
119
  console.log(process.stdout.isTTY && process.stdout.getColorDepth() > 8 ? gradientBanner : defaultBanner);
102
120
  console.log();
103
- const argv2 = minimist(process.argv.slice(2), {
121
+ const argv2 = (0, import_minimist.default)(process.argv.slice(2), {
104
122
  alias: {
105
123
  typescript: ["ts"],
106
124
  "with-tests": ["tests"],
@@ -115,7 +133,7 @@ async function init() {
115
133
  const forceOverwrite = argv2.force;
116
134
  const cwd2 = process.cwd();
117
135
  let result = {};
118
- result = await prompts(
136
+ result = await (0, import_prompts.default)(
119
137
  [
120
138
  {
121
139
  name: "projectName",
@@ -135,20 +153,20 @@ async function init() {
135
153
  ],
136
154
  {
137
155
  onCancel: () => {
138
- throw new Error(chalk.red("\u2716") + " Operation cancelled");
156
+ throw new Error(import_chalk.default.red("\u2716") + " Operation cancelled");
139
157
  }
140
158
  }
141
159
  );
142
160
  const { projectName, shouldOverwrite = argv2.force } = result;
143
- const root = path2.join(cwd2, targetDir);
144
- if (fs3.existsSync(root) && shouldOverwrite) {
161
+ const root = import_path.default.join(cwd2, targetDir);
162
+ if (import_fs.default.existsSync(root) && shouldOverwrite) {
145
163
  emptyDir(root);
146
- } else if (!fs3.existsSync(root)) {
147
- fs3.mkdirSync(root);
164
+ } else if (!import_fs.default.existsSync(root)) {
165
+ import_fs.default.mkdirSync(root);
148
166
  }
149
167
  console.log(`
150
168
  Scaffolding project in ${root}...`);
151
- const templateRoot = path2.join(__dirname, "../template");
169
+ const templateRoot = import_path.default.join(__dirname, "../template");
152
170
  await FileUtils.copyFolderRecursive(templateRoot, root);
153
171
  const userAgent = process.env.npm_config_user_agent ?? "";
154
172
  const packageManager = /pnpm/.test(userAgent) ? "pnpm" : /yarn/.test(userAgent) ? "yarn" : "npm";
@@ -156,10 +174,10 @@ Scaffolding project in ${root}...`);
156
174
  Done. Now run:
157
175
  `);
158
176
  if (root !== cwd2) {
159
- const cdProjectName = path2.relative(cwd2, root);
160
- console.log(` ${chalk.bold(chalk.green(`cd ${cdProjectName.includes(" ") ? `"${cdProjectName}"` : cdProjectName}`))}`);
177
+ const cdProjectName = import_path.default.relative(cwd2, root);
178
+ console.log(` ${import_chalk.default.bold(import_chalk.default.green(`cd ${cdProjectName.includes(" ") ? `"${cdProjectName}"` : cdProjectName}`))}`);
161
179
  }
162
- console.log(` ${chalk.bold(chalk.green(getCommand(packageManager, "install")))}`);
180
+ console.log(` ${import_chalk.default.bold(import_chalk.default.green(getCommand(packageManager, "install")))}`);
163
181
  }
164
182
  init().catch((e) => {
165
183
  console.error(e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-widget",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "main": "lib/index.js",
5
5
  "author": "Neo Fu",
6
6
  "license": "MIT",
@@ -8,7 +8,10 @@
8
8
  "bin": {
9
9
  "create-widget": "lib/index.js"
10
10
  },
11
- "type": "module",
11
+ "files": [
12
+ "lib/index.js",
13
+ "template"
14
+ ],
12
15
  "publishConfig": {
13
16
  "access": "public"
14
17
  },
@@ -16,7 +19,7 @@
16
19
  "node": "^12.0.0 || >= 14.0.0"
17
20
  },
18
21
  "dependencies": {
19
- "chalk": "^5.3.0",
22
+ "chalk": "^4.1.2",
20
23
  "consola": "^2.15.3",
21
24
  "ejs": "^3.1.8",
22
25
  "fs-extra": "^11.2.0",
@@ -39,7 +42,7 @@
39
42
  "vitest": "^0.34.6"
40
43
  },
41
44
  "scripts": {
42
- "build": "rimraf ./lib/ && tsup-node src/index.ts --format esm",
45
+ "build": "rimraf ./lib/ && tsup-node src/index.ts --format cjs",
43
46
  "watch": "tsup-node src/index.ts --format esm --watch",
44
47
  "build:run": "npm run build && npm run create-widget",
45
48
  "create-widget": "node ./lib/index.js",
package/.editorconfig DELETED
@@ -1,13 +0,0 @@
1
- # editorconfig.org
2
- root = true
3
-
4
- [*]
5
- indent_style = space
6
- indent_size = 2
7
- end_of_line = lf
8
- charset = utf-8
9
- trim_trailing_whitespace = true
10
- insert_final_newline = true
11
-
12
- [*.md]
13
- trim_trailing_whitespace = false
@@ -1,9 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="JAVA_MODULE" version="4">
3
- <component name="NewModuleRootManager" inherit-compiler-output="true">
4
- <exclude-output />
5
- <content url="file://$MODULE_DIR$" />
6
- <orderEntry type="inheritedJdk" />
7
- <orderEntry type="sourceFolder" forTests="false" />
8
- </component>
9
- </module>
@@ -1,6 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
- </profile>
6
- </component>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="JpaBuddyIdeaProjectConfig">
4
- <option name="renamerInitialized" value="true" />
5
- </component>
6
- </project>
package/.idea/misc.xml DELETED
@@ -1,8 +0,0 @@
1
- <project version="4">
2
- <component name="ProjectRootManager">
3
- <output url="file://$PROJECT_DIR$/out" />
4
- </component>
5
- <component name="ProjectType">
6
- <option name="id" value="jpab" />
7
- </component>
8
- </project>
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/create-widget.iml" filepath="$PROJECT_DIR$/.idea/create-widget.iml" />
6
- </modules>
7
- </component>
8
- </project>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="PrettierConfiguration">
4
- <option name="myConfigurationMode" value="AUTOMATIC" />
5
- </component>
6
- </project>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
5
- </component>
6
- </project>
package/src/index.ts DELETED
@@ -1,144 +0,0 @@
1
- import fs from 'fs'
2
- import * as process from 'process'
3
- import gradient from 'gradient-string'
4
- import prompts from 'prompts'
5
- import minimist from 'minimist'
6
- import chalk from 'chalk'
7
- import path from 'path'
8
- import {postOrderDirectoryTraverse} from './utils/directoryTraverse'
9
- import getCommand from './utils/getCommand'
10
- import {fileURLToPath} from 'url'
11
- import {FileUtils} from "./utils/FileUtils";
12
-
13
- const __filename = fileURLToPath(import.meta.url)
14
- const __dirname = path.dirname(__filename)
15
-
16
- function canSkipEmptying(dir: string) {
17
- if (!fs.existsSync(dir)) {
18
- return true
19
- }
20
-
21
- const files = fs.readdirSync(dir)
22
- if (files.length === 0) {
23
- return true
24
- }
25
- if (files.length === 1 && files[0] === '.git') {
26
- return true
27
- }
28
-
29
- return false
30
- }
31
-
32
- function emptyDir(dir) {
33
- if (!fs.existsSync(dir)) {
34
- return
35
- }
36
-
37
- postOrderDirectoryTraverse(
38
- dir,
39
- dir => fs.rmdirSync(dir),
40
- file => fs.unlinkSync(file),
41
- )
42
- }
43
-
44
- async function init() {
45
- console.log()
46
- let defaultBanner = 'Widget.js - The Desktop Widget Framework'
47
- const gradientBanner = gradient([
48
- {color: '#42d392', pos: 0},
49
- {color: '#42d392', pos: 0.1},
50
- {color: '#647eff', pos: 1},
51
- ])(defaultBanner)
52
- console.log(process.stdout.isTTY && process.stdout.getColorDepth() > 8 ? gradientBanner : defaultBanner)
53
- console.log()
54
- const argv = minimist(process.argv.slice(2), {
55
- alias: {
56
- typescript: ['ts'],
57
- 'with-tests': ['tests'],
58
- router: ['vue-router'],
59
- },
60
- string: ['_'],
61
- // all arguments are treated as booleans
62
- boolean: true,
63
- })
64
- let targetDir = argv._[0]
65
- const defaultProjectName = !targetDir ? 'widget-project' : targetDir
66
- const forceOverwrite = argv.force
67
-
68
- const cwd = process.cwd()
69
- let result: {
70
- projectName?: string
71
- shouldOverwrite?: boolean
72
- } = {}
73
- result = await prompts(
74
- [
75
- {
76
- name: 'projectName',
77
- type: targetDir ? null : 'text',
78
- message: 'Project name:',
79
- initial: defaultProjectName,
80
- onState: state => (targetDir = String(state.value).trim() || defaultProjectName),
81
- },
82
- {
83
- name: 'shouldOverwrite',
84
- type: () => (canSkipEmptying(targetDir) || forceOverwrite ? null : 'confirm'),
85
- message: () => {
86
- const dirForPrompt = targetDir === '.' ? 'Current directory' : `Target directory "${targetDir}"`
87
- return `${dirForPrompt} is not empty. Remove existing files and continue?`
88
- },
89
- },
90
- ],
91
- {
92
- onCancel: () => {
93
- throw new Error(chalk.red('✖') + ' Operation cancelled')
94
- },
95
- },
96
- )
97
-
98
- // `initial` won't take effect if the prompt type is null
99
- // so we still have to assign the default values here
100
- const {projectName, shouldOverwrite = argv.force} = result
101
-
102
- const root = path.join(cwd, targetDir)
103
-
104
- if (fs.existsSync(root) && shouldOverwrite) {
105
- emptyDir(root)
106
- } else if (!fs.existsSync(root)) {
107
- fs.mkdirSync(root)
108
- }
109
-
110
- console.log(`\nScaffolding project in ${root}...`)
111
-
112
- const templateRoot = path.join(__dirname, '../template')
113
-
114
- //复制templateRoot下的文件到root目录下
115
- await FileUtils.copyFolderRecursive(templateRoot, root)
116
-
117
- // const callbacks = []
118
- //
119
- // const render = function render(templateName) {
120
- // const templateDir = path.resolve(templateRoot, templateName)
121
- // renderTemplate(templateDir, root, callbacks)
122
- // }
123
- // // 将template里的文件都复制到 root目录下
124
- // const templateFiles = fs.readdirSync(templateRoot)
125
- // for (const file of templateFiles) {
126
- // render(file)
127
- // }
128
-
129
- // Instructions:
130
- // Supported package managers: pnpm > yarn > npm
131
- const userAgent = process.env.npm_config_user_agent ?? ''
132
- const packageManager = /pnpm/.test(userAgent) ? 'pnpm' : /yarn/.test(userAgent) ? 'yarn' : 'npm'
133
-
134
- console.log(`\nDone. Now run:\n`)
135
- if (root !== cwd) {
136
- const cdProjectName = path.relative(cwd, root)
137
- console.log(` ${chalk.bold(chalk.green(`cd ${cdProjectName.includes(' ') ? `"${cdProjectName}"` : cdProjectName}`))}`)
138
- }
139
- console.log(` ${chalk.bold(chalk.green(getCommand(packageManager, 'install')))}`)
140
- }
141
-
142
- init().catch(e => {
143
- console.error(e)
144
- })
@@ -1,33 +0,0 @@
1
- import * as fs from 'fs'
2
- import {copy,ensureDir} from "fs-extra";
3
-
4
- export class FileUtils {
5
- static async copyFolderRecursive(src: string, dest: string): Promise<void> {
6
- try {
7
- // 创建目标文件夹
8
- await ensureDir(dest)
9
-
10
- // 获取源文件夹中的所有文件和子文件夹
11
- const items = await fs.promises.readdir(src)
12
-
13
- // 遍历每一个文件或子文件夹
14
- for (const item of items) {
15
- const srcPath = `${src}/${item}`
16
- const destPath = `${dest}/${item}`
17
-
18
- // 检查当前项目是文件还是文件夹
19
- const stats = await fs.promises.stat(srcPath)
20
-
21
- if (stats.isDirectory()) {
22
- // 如果是文件夹,递归复制
23
- await this.copyFolderRecursive(srcPath, destPath)
24
- } else {
25
- // 如果是文件,直接复制
26
- await copy(srcPath, destPath)
27
- }
28
- }
29
- } catch (error) {
30
- console.error(`Error copying folder: ${error.message}`)
31
- }
32
- }
33
- }
@@ -1,26 +0,0 @@
1
- const isObject = (val) => val && typeof val === 'object'
2
- const mergeArrayWithDedupe = (a, b) => Array.from(new Set([...a, ...b]))
3
-
4
- /**
5
- * Recursively merge the content of the new object to the existing one
6
- * @param {Object} target the existing object
7
- * @param {Object} obj the new object
8
- */
9
- function deepMerge(target, obj) {
10
- for (const key of Object.keys(obj)) {
11
- const oldVal = target[key]
12
- const newVal = obj[key]
13
-
14
- if (Array.isArray(oldVal) && Array.isArray(newVal)) {
15
- target[key] = mergeArrayWithDedupe(oldVal, newVal)
16
- } else if (isObject(oldVal) && isObject(newVal)) {
17
- target[key] = deepMerge(oldVal, newVal)
18
- } else {
19
- target[key] = newVal
20
- }
21
- }
22
-
23
- return target
24
- }
25
-
26
- export default deepMerge
@@ -1,35 +0,0 @@
1
- import * as fs from 'node:fs'
2
- import * as path from 'node:path'
3
-
4
- export function preOrderDirectoryTraverse(dir, dirCallback, fileCallback) {
5
- for (const filename of fs.readdirSync(dir)) {
6
- if (filename === '.git') {
7
- continue
8
- }
9
- const fullpath = path.resolve(dir, filename)
10
- if (fs.lstatSync(fullpath).isDirectory()) {
11
- dirCallback(fullpath)
12
- // in case the dirCallback removes the directory entirely
13
- if (fs.existsSync(fullpath)) {
14
- preOrderDirectoryTraverse(fullpath, dirCallback, fileCallback)
15
- }
16
- continue
17
- }
18
- fileCallback(fullpath)
19
- }
20
- }
21
-
22
- export function postOrderDirectoryTraverse(dir, dirCallback, fileCallback) {
23
- for (const filename of fs.readdirSync(dir)) {
24
- if (filename === '.git') {
25
- continue
26
- }
27
- const fullpath = path.resolve(dir, filename)
28
- if (fs.lstatSync(fullpath).isDirectory()) {
29
- postOrderDirectoryTraverse(fullpath, dirCallback, fileCallback)
30
- dirCallback(fullpath)
31
- continue
32
- }
33
- fileCallback(fullpath)
34
- }
35
- }
@@ -1,13 +0,0 @@
1
- export default function getCommand(packageManager: string, scriptName: string, args?: string) {
2
- if (scriptName === 'install') {
3
- return packageManager === 'yarn' ? 'yarn' : `${packageManager} install`
4
- }
5
-
6
- if (args) {
7
- return packageManager === 'npm'
8
- ? `npm run ${scriptName} -- ${args}`
9
- : `${packageManager} ${scriptName} ${args}`
10
- } else {
11
- return packageManager === 'npm' ? `npm run ${scriptName}` : `${packageManager} ${scriptName}`
12
- }
13
- }
@@ -1,88 +0,0 @@
1
- import * as fs from 'node:fs'
2
- import * as path from 'node:path'
3
- import { pathToFileURL } from 'node:url'
4
-
5
- import deepMerge from './deepMerge'
6
- import sortDependencies from './sortDependencies'
7
-
8
- /**
9
- * Renders a template folder/file to the file system,
10
- * by recursively copying all files under the `src` directory,
11
- * with the following exception:
12
- * - `_filename` should be renamed to `.filename`
13
- * - Fields in `package.json` should be recursively merged
14
- * @param {string} src source filename to copy
15
- * @param {string} dest destination filename of the copy operation
16
- */
17
- function renderTemplate(src, dest, callbacks) {
18
- const stats = fs.statSync(src)
19
-
20
- if (stats.isDirectory()) {
21
- // skip node_module
22
- if (path.basename(src) === 'node_modules') {
23
- return
24
- }
25
-
26
- // if it's a directory, render its subdirectories and files recursively
27
- fs.mkdirSync(dest, { recursive: true })
28
- for (const file of fs.readdirSync(src)) {
29
- renderTemplate(path.resolve(src, file), path.resolve(dest, file), callbacks)
30
- }
31
- return
32
- }
33
-
34
- const filename = path.basename(src)
35
-
36
- if (filename === 'package.json' && fs.existsSync(dest)) {
37
- // merge instead of overwriting
38
- const existing = JSON.parse(fs.readFileSync(dest, 'utf8'))
39
- const newPackage = JSON.parse(fs.readFileSync(src, 'utf8'))
40
- const pkg = sortDependencies(deepMerge(existing, newPackage))
41
- fs.writeFileSync(dest, JSON.stringify(pkg, null, 2) + '\n')
42
- return
43
- }
44
-
45
- if (filename === 'extensions.json' && fs.existsSync(dest)) {
46
- // merge instead of overwriting
47
- const existing = JSON.parse(fs.readFileSync(dest, 'utf8'))
48
- const newExtensions = JSON.parse(fs.readFileSync(src, 'utf8'))
49
- const extensions = deepMerge(existing, newExtensions)
50
- fs.writeFileSync(dest, JSON.stringify(extensions, null, 2) + '\n')
51
- return
52
- }
53
-
54
- if (filename.startsWith('_')) {
55
- // rename `_file` to `.file`
56
- dest = path.resolve(path.dirname(dest), filename.replace(/^_/, '.'))
57
- }
58
-
59
- if (filename === '_gitignore' && fs.existsSync(dest)) {
60
- // append to existing .gitignore
61
- const existing = fs.readFileSync(dest, 'utf8')
62
- const newGitignore = fs.readFileSync(src, 'utf8')
63
- fs.writeFileSync(dest, existing + '\n' + newGitignore)
64
- return
65
- }
66
-
67
- // data file for EJS templates
68
- if (filename.endsWith('.data.mjs')) {
69
- // use dest path as key for the data store
70
- dest = dest.replace(/\.data\.mjs$/, '')
71
-
72
- // Add a callback to the array for late usage when template files are being processed
73
- callbacks.push(async (dataStore) => {
74
- const getData = (await import(pathToFileURL(src).toString())).default
75
-
76
- // Though current `getData` are all sync, we still retain the possibility of async
77
- dataStore[dest] = await getData({
78
- oldData: dataStore[dest] || {}
79
- })
80
- })
81
-
82
- return // skip copying the data file
83
- }
84
-
85
- fs.copyFileSync(src, dest)
86
- }
87
-
88
- export default renderTemplate
@@ -1,22 +0,0 @@
1
- export default function sortDependencies(packageJson) {
2
- const sorted = {}
3
-
4
- const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']
5
-
6
- for (const depType of depTypes) {
7
- if (packageJson[depType]) {
8
- sorted[depType] = {}
9
-
10
- Object.keys(packageJson[depType])
11
- .sort()
12
- .forEach((name) => {
13
- sorted[depType][name] = packageJson[depType][name]
14
- })
15
- }
16
- }
17
-
18
- return {
19
- ...packageJson,
20
- ...sorted
21
- }
22
- }