@tsparticles/cli-command-create 4.0.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.cache/eslint/.eslintcache +1 -0
  2. package/.dependency-cruiser.cjs +382 -0
  3. package/LICENSE +21 -0
  4. package/README.md +51 -0
  5. package/dist/create.d.ts +3 -0
  6. package/dist/create.js +10 -0
  7. package/dist/plugin/create-plugin.d.ts +8 -0
  8. package/dist/plugin/create-plugin.js +136 -0
  9. package/dist/plugin/plugin.d.ts +3 -0
  10. package/dist/plugin/plugin.js +34 -0
  11. package/dist/preset/create-preset.d.ts +8 -0
  12. package/dist/preset/create-preset.js +154 -0
  13. package/dist/preset/preset.d.ts +3 -0
  14. package/dist/preset/preset.js +34 -0
  15. package/dist/shape/create-shape.d.ts +8 -0
  16. package/dist/shape/create-shape.js +137 -0
  17. package/dist/shape/shape.d.ts +3 -0
  18. package/dist/shape/shape.js +34 -0
  19. package/dist/tsconfig.tsbuildinfo +1 -0
  20. package/eslint.config.js +22 -0
  21. package/files/create-plugin/README.md +74 -0
  22. package/files/create-plugin/src/PluginInstance.ts +18 -0
  23. package/files/create-plugin/src/browser.ts +10 -0
  24. package/files/create-plugin/src/index.lazy.ts +10 -0
  25. package/files/create-plugin/src/index.ts +9 -0
  26. package/files/create-plugin/src/plugin.ts +36 -0
  27. package/files/create-preset/README.md +144 -0
  28. package/files/create-preset/images/sample.png +0 -0
  29. package/files/create-preset/src/browser.ts +10 -0
  30. package/files/create-preset/src/bundle.ts +17 -0
  31. package/files/create-preset/src/index.lazy.ts +14 -0
  32. package/files/create-preset/src/index.ts +13 -0
  33. package/files/create-preset/src/options.ts +6 -0
  34. package/files/create-shape/README.md +75 -0
  35. package/files/create-shape/src/ShapeDrawer.ts +16 -0
  36. package/files/create-shape/src/browser.ts +10 -0
  37. package/files/create-shape/src/index.lazy.ts +10 -0
  38. package/files/create-shape/src/index.ts +9 -0
  39. package/package.json +81 -0
  40. package/renovate.json +9 -0
  41. package/src/create.ts +14 -0
  42. package/src/plugin/create-plugin.ts +198 -0
  43. package/src/plugin/plugin.ts +46 -0
  44. package/src/preset/create-preset.ts +218 -0
  45. package/src/preset/preset.ts +46 -0
  46. package/src/shape/create-shape.ts +200 -0
  47. package/src/shape/shape.ts +46 -0
  48. package/src/tsconfig.json +9 -0
  49. package/tests/create-plugin.test.ts +40 -0
  50. package/tests/create-preset.test.ts +40 -0
  51. package/tests/create-shape.test.ts +40 -0
  52. package/tests/tsconfig.json +15 -0
  53. package/tsconfig.json +53 -0
  54. package/vitest.config.ts +11 -0
@@ -0,0 +1,198 @@
1
+ import {
2
+ camelize,
3
+ capitalize,
4
+ copyEmptyTemplateFiles,
5
+ copyFilter,
6
+ dash,
7
+ replaceTokensInFile,
8
+ runBuild,
9
+ runInstall,
10
+ updatePackageDistFile,
11
+ updatePackageFile,
12
+ updateWebpackFile,
13
+ } from "@tsparticles/cli-create-utils";
14
+ import { cp } from "node:fs/promises";
15
+ import path from "node:path";
16
+
17
+ /**
18
+ * Updates the index file with the correct function name
19
+ * @param destPath - The path where the project is located
20
+ * @param name - The name of the project
21
+ */
22
+ async function updateIndexFile(destPath: string, name: string): Promise<void> {
23
+ const capitalizedName = capitalize(name, "-", " "),
24
+ camelizedName = camelize(capitalizedName);
25
+
26
+ await replaceTokensInFile({
27
+ path: path.join(destPath, "src", "index.ts"),
28
+ tokens: [
29
+ {
30
+ from: /loadTemplatePlugin/g,
31
+ to: `load${capitalizedName}Plugin`,
32
+ },
33
+ {
34
+ from: /"#template#"/g,
35
+ to: `"${camelizedName}"`,
36
+ },
37
+ ],
38
+ });
39
+
40
+ await replaceTokensInFile({
41
+ path: path.join(destPath, "src", "index.lazy.ts"),
42
+ tokens: [
43
+ {
44
+ from: /loadTemplatePlugin/g,
45
+ to: `load${capitalizedName}Plugin`,
46
+ },
47
+ {
48
+ from: /"#template#"/g,
49
+ to: `"${camelizedName}"`,
50
+ },
51
+ ],
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Updates the plugin package file
57
+ * @param destPath - The path where the project is located
58
+ * @param name - The name of the project
59
+ * @param description - The description of the project
60
+ * @param repoUrl - The repository url
61
+ */
62
+ async function updatePluginPackageFile(
63
+ destPath: string,
64
+ name: string,
65
+ description: string,
66
+ repoUrl: string,
67
+ ): Promise<void> {
68
+ const camelizedName = camelize(camelize(name, "-"), " "),
69
+ dashedName = dash(camelizedName);
70
+
71
+ await updatePackageFile(
72
+ destPath,
73
+ `tsparticles-plugin-${dashedName}`,
74
+ description,
75
+ `tsparticles.plugin.${camelizedName}.min.js`,
76
+ repoUrl,
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Updates the plugin package dist file
82
+ * @param destPath - The path where the project is located
83
+ * @param name - The name of the project
84
+ * @param description - The description of the project
85
+ * @param repoUrl - The repository url
86
+ */
87
+ async function updatePluginPackageDistFile(
88
+ destPath: string,
89
+ name: string,
90
+ description: string,
91
+ repoUrl: string,
92
+ ): Promise<void> {
93
+ const camelizedName = camelize(camelize(name, "-"), " "),
94
+ dashedName = dash(camelizedName);
95
+
96
+ await updatePackageDistFile(
97
+ destPath,
98
+ `tsparticles-plugin-${dashedName}`,
99
+ description,
100
+ `tsparticles.plugin.${camelizedName}.min.js`,
101
+ repoUrl,
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Updates the plugin readme file
107
+ * @param destPath - The path where the project is located
108
+ * @param name - The name of the project
109
+ * @param description - The description of the project
110
+ * @param repoUrl - The repository url
111
+ */
112
+ async function updateReadmeFile(destPath: string, name: string, description: string, repoUrl: string): Promise<void> {
113
+ const readmePath = path.join(destPath, "README.md"),
114
+ capitalizedName = capitalize(name, "-", " "),
115
+ camelizedName = camelize(capitalizedName),
116
+ dashedName = dash(camelizedName),
117
+ stringSearch = "github.com",
118
+ trailingSlashSearch = "github.com/",
119
+ repoPath = repoUrl.includes(stringSearch)
120
+ ? repoUrl.substring(repoUrl.indexOf(trailingSlashSearch) + trailingSlashSearch.length, repoUrl.indexOf(".git"))
121
+ : "tsparticles/plugin-template";
122
+
123
+ await replaceTokensInFile({
124
+ path: readmePath,
125
+ tokens: [
126
+ {
127
+ from: /tsParticles Template Plugin/g,
128
+ to: `tsParticles ${description} Plugin`,
129
+ },
130
+ {
131
+ from: /tsparticles-plugin-template/g,
132
+ to: `tsparticles-plugin-${dashedName}`,
133
+ },
134
+ {
135
+ from: /tsparticles\.plugin\.template(\.bundle)?\.min\.js/g,
136
+ to: `tsparticles.plugin.${camelizedName}$1.min.js`,
137
+ },
138
+ {
139
+ from: /loadTemplatePlugin/g,
140
+ to: `load${capitalizedName}Plugin`,
141
+ },
142
+ {
143
+ from: /\[tsParticles]\(https:\/\/github.com\/matteobruni\/tsparticles\) additional template plugin\./g,
144
+ to: `[tsParticles](https://github.com/matteobruni/tsparticles) additional ${name} plugin.`,
145
+ },
146
+ {
147
+ from: /plugin\.type: "template"/g,
148
+ to: `plugin.type: "${camelizedName}"`,
149
+ },
150
+ {
151
+ from: /!\[demo]\(https:\/\/raw.githubusercontent.com\/tsparticles\/plugin-template\/main\/images\/sample.png\)/g,
152
+ to: `![demo](https://raw.githubusercontent.com/${repoPath}/main/images/sample.png)`,
153
+ },
154
+ ],
155
+ });
156
+ }
157
+
158
+ /**
159
+ * Updates the plugin webpack file
160
+ * @param destPath - The path where the project is located
161
+ * @param name - The name of the project
162
+ * @param description - The description of the project
163
+ */
164
+ async function updatePluginWebpackFile(destPath: string, name: string, description: string): Promise<void> {
165
+ await updateWebpackFile(destPath, camelize(capitalize(name, "-", " ")), description, "loadParticlesPlugin");
166
+ }
167
+
168
+ /**
169
+ * Creates the plugin project
170
+ * @param name - The name of the project
171
+ * @param description - The description of the project
172
+ * @param repoUrl - The repository url
173
+ * @param destPath - The path where the project is located
174
+ */
175
+ export async function createPluginTemplate(
176
+ name: string,
177
+ description: string,
178
+ repoUrl: string,
179
+ destPath: string,
180
+ ): Promise<void> {
181
+ const sourcePath = path.join(__dirname, "..", "..", "files", "create-plugin");
182
+
183
+ await copyEmptyTemplateFiles(destPath);
184
+
185
+ await cp(sourcePath, destPath, {
186
+ recursive: true,
187
+ force: true,
188
+ filter: copyFilter,
189
+ });
190
+
191
+ await updateIndexFile(destPath, name);
192
+ await updatePluginPackageFile(destPath, name, description, repoUrl);
193
+ await updatePluginPackageDistFile(destPath, name, description, repoUrl);
194
+ await updateReadmeFile(destPath, name, description, repoUrl);
195
+ await updatePluginWebpackFile(destPath, name, description);
196
+ await runInstall(destPath);
197
+ await runBuild(destPath);
198
+ }
@@ -0,0 +1,46 @@
1
+ import { capitalize, getDestinationDir, getRepositoryUrl } from "@tsparticles/cli-create-utils";
2
+ import prompts, { type PromptObject } from "prompts";
3
+ import { Command } from "commander";
4
+ import { createPluginTemplate } from "./create-plugin.js";
5
+ import path from "node:path";
6
+
7
+ const pluginCommand = new Command("plugin");
8
+
9
+ pluginCommand.description("Create a new tsParticles plugin");
10
+ pluginCommand.argument("<destination>", "Destination folder");
11
+ pluginCommand.action(async (destination: string) => {
12
+ const destPath = await getDestinationDir(destination),
13
+ repoUrl = await getRepositoryUrl(),
14
+ initialName = destPath.split(path.sep).pop(),
15
+ questions: PromptObject[] = [
16
+ {
17
+ type: "text",
18
+ name: "name",
19
+ message: "What is the name of the plugin?",
20
+ validate: (value: string) => (value ? true : "The name can't be empty"),
21
+ initial: initialName,
22
+ },
23
+ {
24
+ type: "text",
25
+ name: "description",
26
+ message: "What is the description of the plugin?",
27
+ validate: (value: string) => (value ? true : "The description can't be empty"),
28
+ initial: capitalize(initialName ?? ""),
29
+ },
30
+ {
31
+ type: "text",
32
+ name: "repositoryUrl",
33
+ message: "What is the repository URL? (optional)",
34
+ initial: repoUrl.trim(),
35
+ },
36
+ ],
37
+ { name, description, repositoryUrl } = (await prompts(questions)) as {
38
+ description: string;
39
+ name: string;
40
+ repositoryUrl: string;
41
+ };
42
+
43
+ await createPluginTemplate(name.trim(), description.trim(), repositoryUrl.trim(), destPath);
44
+ });
45
+
46
+ export { pluginCommand };
@@ -0,0 +1,218 @@
1
+ import {
2
+ camelize,
3
+ capitalize,
4
+ copyEmptyTemplateFiles,
5
+ copyFilter,
6
+ dash,
7
+ replaceTokensInFile,
8
+ runBuild,
9
+ runInstall,
10
+ updatePackageDistFile,
11
+ updatePackageFile,
12
+ updateWebpackFile,
13
+ } from "@tsparticles/cli-create-utils";
14
+ import { cp } from "node:fs/promises";
15
+ import path from "node:path";
16
+
17
+ /**
18
+ * Updates the bundle file with the correct function name
19
+ * @param destPath - The path where the project is located
20
+ * @param name - The name of the project
21
+ */
22
+ async function updateBundleFile(destPath: string, name: string): Promise<void> {
23
+ const capitalizedName = capitalize(name, "-", " ");
24
+
25
+ await replaceTokensInFile({
26
+ path: path.join(destPath, "src", "bundle.ts"),
27
+ tokens: [
28
+ {
29
+ from: /loadTemplatePreset/g,
30
+ to: `load${capitalizedName}Preset`,
31
+ },
32
+ ],
33
+ });
34
+ }
35
+
36
+ /**
37
+ * Updates the index file with the correct function name
38
+ * @param destPath - The path where the project is located
39
+ * @param name - The name of the project
40
+ */
41
+ async function updateIndexFile(destPath: string, name: string): Promise<void> {
42
+ const capitalizedName = capitalize(name, "-", " "),
43
+ camelizedName = camelize(capitalizedName);
44
+
45
+ await replaceTokensInFile({
46
+ path: path.join(destPath, "src", "index.ts"),
47
+ tokens: [
48
+ {
49
+ from: /loadTemplatePreset/g,
50
+ to: `load${capitalizedName}Preset`,
51
+ },
52
+ {
53
+ from: /"#template#"/g,
54
+ to: `"${camelizedName}"`,
55
+ },
56
+ ],
57
+ });
58
+
59
+ await replaceTokensInFile({
60
+ path: path.join(destPath, "src", "index.lazy.ts"),
61
+ tokens: [
62
+ {
63
+ from: /loadTemplatePreset/g,
64
+ to: `load${capitalizedName}Preset`,
65
+ },
66
+ {
67
+ from: /"#template#"/g,
68
+ to: `"${camelizedName}"`,
69
+ },
70
+ ],
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Updates the preset package file
76
+ * @param destPath - The path where the project is located
77
+ * @param name - The name of the project
78
+ * @param description - The description of the project
79
+ * @param repoUrl - The repository url
80
+ */
81
+ async function updatePresetPackageFile(
82
+ destPath: string,
83
+ name: string,
84
+ description: string,
85
+ repoUrl: string,
86
+ ): Promise<void> {
87
+ const camelizedName = camelize(name, "-", " "),
88
+ dashedName = dash(camelizedName);
89
+
90
+ await updatePackageFile(
91
+ destPath,
92
+ `tsparticles-preset-${dashedName}`,
93
+ description,
94
+ `tsparticles.preset.${camelizedName}.min.js`,
95
+ repoUrl,
96
+ );
97
+ }
98
+
99
+ /**
100
+ * Updates the preset package dist file
101
+ * @param destPath - The path where the project is located
102
+ * @param name - The name of the project
103
+ * @param description - The description of the project
104
+ * @param repoUrl - The repository url
105
+ */
106
+ async function updatePresetPackageDistFile(
107
+ destPath: string,
108
+ name: string,
109
+ description: string,
110
+ repoUrl: string,
111
+ ): Promise<void> {
112
+ const camelizedName = camelize(name, "-", " "),
113
+ dashedName = dash(camelizedName);
114
+
115
+ await updatePackageDistFile(
116
+ destPath,
117
+ `tsparticles-preset-${dashedName}`,
118
+ description,
119
+ `tsparticles.preset.${camelizedName}.min.js`,
120
+ repoUrl,
121
+ );
122
+ }
123
+
124
+ /**
125
+ * Updates the preset readme file
126
+ * @param destPath - The path where the project is located
127
+ * @param name - The name of the project
128
+ * @param description - The description of the project
129
+ * @param repoUrl - The repository url
130
+ */
131
+ async function updateReadmeFile(destPath: string, name: string, description: string, repoUrl: string): Promise<void> {
132
+ const capitalizedName = capitalize(name, "-", " "),
133
+ camelizedName = camelize(capitalizedName),
134
+ dashedName = dash(camelizedName),
135
+ stringSearch = "github.com",
136
+ trailingSlashSearch = "github.com/",
137
+ repoPath = repoUrl.includes(stringSearch)
138
+ ? repoUrl.substring(repoUrl.indexOf(trailingSlashSearch) + trailingSlashSearch.length, repoUrl.indexOf(".git"))
139
+ : "tsparticles/preset-template";
140
+
141
+ await replaceTokensInFile({
142
+ path: path.join(destPath, "README.md"),
143
+ tokens: [
144
+ {
145
+ from: /tsParticles Template Preset/g,
146
+ to: `tsParticles ${description} Preset`,
147
+ },
148
+ {
149
+ from: /tsparticles-preset-template/g,
150
+ to: `tsparticles-preset-${dashedName}`,
151
+ },
152
+ {
153
+ from: /tsparticles\.preset\.template(\.bundle)?\.min\.js/g,
154
+ to: `tsparticles.preset.${camelizedName}$1.min.js`,
155
+ },
156
+ {
157
+ from: /loadTemplatePreset/g,
158
+ to: `load${capitalizedName}Preset`,
159
+ },
160
+ {
161
+ from: /\[tsParticles]\(https:\/\/github.com\/matteobruni\/tsparticles\) preset template\./g,
162
+ to: `[tsParticles](https://github.com/matteobruni/tsparticles) preset ${name}.`,
163
+ },
164
+ {
165
+ from: /preset: "template"/g,
166
+ to: `preset: "${camelizedName}`,
167
+ },
168
+ {
169
+ from: /!\[demo]\(https:\/\/raw.githubusercontent.com\/tsparticles\/preset-template\/main\/images\/sample.png\)/g,
170
+ to: `![demo](https://raw.githubusercontent.com/${repoPath}/main/images/sample.png)`,
171
+ },
172
+ ],
173
+ });
174
+ }
175
+
176
+ /**
177
+ * Updates the preset webpack file
178
+ * @param destPath - The path where the project is located
179
+ * @param name - The name of the project
180
+ * @param description - The description of the project
181
+ */
182
+ async function updatePresetWebpackFile(destPath: string, name: string, description: string): Promise<void> {
183
+ await updateWebpackFile(destPath, camelize(capitalize(name, "-", " ")), description, "loadParticlesPreset");
184
+ }
185
+
186
+ /**
187
+ * Creates the preset project
188
+ * @param name - The name of the project
189
+ * @param description - The description of the project
190
+ * @param repoUrl - The repository url
191
+ * @param destPath - The path where the project is located
192
+ */
193
+ export async function createPresetTemplate(
194
+ name: string,
195
+ description: string,
196
+ repoUrl: string,
197
+ destPath: string,
198
+ ): Promise<void> {
199
+ const sourcePath = path.join(__dirname, "..", "..", "files", "create-preset");
200
+
201
+ await copyEmptyTemplateFiles(destPath);
202
+
203
+ await cp(sourcePath, destPath, {
204
+ recursive: true,
205
+ force: true,
206
+ filter: copyFilter,
207
+ });
208
+
209
+ await updateBundleFile(destPath, name);
210
+ await updateIndexFile(destPath, name);
211
+ await updatePresetPackageFile(destPath, name, description, repoUrl);
212
+ await updatePresetPackageDistFile(destPath, name, description, repoUrl);
213
+ await updateReadmeFile(destPath, name, description, repoUrl);
214
+ await updatePresetWebpackFile(destPath, name, description);
215
+
216
+ await runInstall(destPath);
217
+ await runBuild(destPath);
218
+ }
@@ -0,0 +1,46 @@
1
+ import { capitalize, getDestinationDir, getRepositoryUrl } from "@tsparticles/cli-create-utils";
2
+ import prompts, { type PromptObject } from "prompts";
3
+ import { Command } from "commander";
4
+ import { createPresetTemplate } from "./create-preset.js";
5
+ import path from "node:path";
6
+
7
+ const presetCommand = new Command("preset");
8
+
9
+ presetCommand.description("Create a new tsParticles preset");
10
+ presetCommand.argument("<destination>", "Destination folder");
11
+ presetCommand.action(async (destination: string) => {
12
+ const destPath = await getDestinationDir(destination),
13
+ repoUrl = await getRepositoryUrl(),
14
+ initialName = destPath.split(path.sep).pop(),
15
+ questions: PromptObject[] = [
16
+ {
17
+ type: "text",
18
+ name: "name",
19
+ message: "What is the name of the preset?",
20
+ validate: (value: string) => (value ? true : "The name can't be empty"),
21
+ initial: initialName,
22
+ },
23
+ {
24
+ type: "text",
25
+ name: "description",
26
+ message: "What is the description of the preset?",
27
+ validate: (value: string) => (value ? true : "The description can't be empty"),
28
+ initial: capitalize(initialName ?? ""),
29
+ },
30
+ {
31
+ type: "text",
32
+ name: "repositoryUrl",
33
+ message: "What is the repository URL? (optional)",
34
+ initial: repoUrl.trim(),
35
+ },
36
+ ],
37
+ { name, description, repositoryUrl } = (await prompts(questions)) as {
38
+ description: string;
39
+ name: string;
40
+ repositoryUrl: string;
41
+ };
42
+
43
+ await createPresetTemplate(name.trim(), description.trim(), repositoryUrl.trim(), destPath);
44
+ });
45
+
46
+ export { presetCommand };
@@ -0,0 +1,200 @@
1
+ import {
2
+ camelize,
3
+ capitalize,
4
+ copyEmptyTemplateFiles,
5
+ copyFilter,
6
+ dash,
7
+ replaceTokensInFile,
8
+ runBuild,
9
+ runInstall,
10
+ updatePackageDistFile,
11
+ updatePackageFile,
12
+ updateWebpackFile,
13
+ } from "@tsparticles/cli-create-utils";
14
+ import { cp } from "node:fs/promises";
15
+ import path from "node:path";
16
+
17
+ /**
18
+ * Updates the index file with the correct function name
19
+ * @param destPath - The path where the project is located
20
+ * @param name - The name of the project
21
+ */
22
+ async function updateIndexFile(destPath: string, name: string): Promise<void> {
23
+ const capitalizedName = capitalize(name, "-", " "),
24
+ camelizedName = camelize(capitalizedName);
25
+
26
+ await replaceTokensInFile({
27
+ path: path.join(destPath, "src", "index.ts"),
28
+ tokens: [
29
+ {
30
+ from: /loadTemplateShape/g,
31
+ to: `load${capitalizedName}Shape`,
32
+ },
33
+ ],
34
+ });
35
+
36
+ await replaceTokensInFile({
37
+ path: path.join(destPath, "src", "index.lazy.ts"),
38
+ tokens: [
39
+ {
40
+ from: /loadTemplateShape/g,
41
+ to: `load${capitalizedName}Shape`,
42
+ },
43
+ ],
44
+ });
45
+
46
+ await replaceTokensInFile({
47
+ path: path.join(destPath, "src", "ShapeDrawer.ts"),
48
+ tokens: [
49
+ {
50
+ from: /"#template#"/g,
51
+ to: `"${camelizedName}"`,
52
+ },
53
+ ],
54
+ });
55
+ }
56
+
57
+ /**
58
+ * Updates the shape package file
59
+ * @param destPath - The path where the project is located
60
+ * @param name - The name of the project
61
+ * @param description - The description of the project
62
+ * @param repoUrl - The repository url
63
+ */
64
+ async function updateShapePackageFile(
65
+ destPath: string,
66
+ name: string,
67
+ description: string,
68
+ repoUrl: string,
69
+ ): Promise<void> {
70
+ const camelizedName = camelize(camelize(name, "-"), " "),
71
+ dashedName = dash(camelizedName);
72
+
73
+ await updatePackageFile(
74
+ destPath,
75
+ `tsparticles-shape-${dashedName}`,
76
+ description,
77
+ `tsparticles.shape.${camelizedName}.min.js`,
78
+ repoUrl,
79
+ );
80
+ }
81
+
82
+ /**
83
+ * Updates the shape package dist file
84
+ * @param destPath - The path where the project is located
85
+ * @param name - The name of the project
86
+ * @param description - The description of the project
87
+ * @param repoUrl - The repository url
88
+ */
89
+ async function updateShapePackageDistFile(
90
+ destPath: string,
91
+ name: string,
92
+ description: string,
93
+ repoUrl: string,
94
+ ): Promise<void> {
95
+ const camelizedName = camelize(camelize(name, "-"), " "),
96
+ dashedName = dash(camelizedName);
97
+
98
+ await updatePackageDistFile(
99
+ destPath,
100
+ `tsparticles-shape-${dashedName}`,
101
+ description,
102
+ `tsparticles.shape.${camelizedName}.min.js`,
103
+ repoUrl,
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Updates the shape readme file
109
+ * @param destPath - The path where the project is located
110
+ * @param name - The name of the project
111
+ * @param description - The description of the project
112
+ * @param repoUrl - The repository url
113
+ */
114
+ async function updateReadmeFile(destPath: string, name: string, description: string, repoUrl: string): Promise<void> {
115
+ const capitalizedName = capitalize(name, "-", " "),
116
+ camelizedName = camelize(capitalizedName),
117
+ dashedName = dash(camelizedName),
118
+ stringSearch = "github.com",
119
+ trailingSlashSearch = "github.com/",
120
+ repoPath = repoUrl.includes(stringSearch)
121
+ ? repoUrl.substring(repoUrl.indexOf(trailingSlashSearch) + trailingSlashSearch.length, repoUrl.indexOf(".git"))
122
+ : "tsparticles/shape-template";
123
+
124
+ await replaceTokensInFile({
125
+ path: path.join(destPath, "README.md"),
126
+ tokens: [
127
+ {
128
+ from: /tsParticles Template Shape/g,
129
+ to: `tsParticles ${description} Shape`,
130
+ },
131
+ {
132
+ from: /tsparticles-shape-template/g,
133
+ to: `tsparticles-shape-${dashedName}`,
134
+ },
135
+ {
136
+ from: /tsparticles\.shape\.template(\.bundle)?\.min\.js/g,
137
+ to: `tsparticles.shape.${camelizedName}$1.min.js`,
138
+ },
139
+ {
140
+ from: /loadTemplateShape/g,
141
+ to: `load${capitalizedName}Shape`,
142
+ },
143
+ {
144
+ from: /\[tsParticles]\(https:\/\/github.com\/matteobruni\/tsparticles\) additional template shape\./g,
145
+ to: `[tsParticles](https://github.com/matteobruni/tsparticles) additional ${name} shape.`,
146
+ },
147
+ {
148
+ from: /shape\.type: "template"/g,
149
+ to: `shape.type: "${camelizedName}`,
150
+ },
151
+ {
152
+ from: /!\[demo]\(https:\/\/raw.githubusercontent.com\/tsparticles\/shape-template\/main\/images\/sample.png\)/g,
153
+ to: `![demo](https://raw.githubusercontent.com/${repoPath}/main/images/sample.png)`,
154
+ },
155
+ ],
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Updates the shape webpack file
161
+ * @param destPath - The path where the project is located
162
+ * @param name - The name of the project
163
+ * @param description - The description of the project
164
+ */
165
+ async function updateShapeWebpackFile(destPath: string, name: string, description: string): Promise<void> {
166
+ await updateWebpackFile(destPath, camelize(capitalize(name, "-", " ")), description, "loadParticlesShape");
167
+ }
168
+
169
+ /**
170
+ * Creates the shape project
171
+ * @param name - The name of the project
172
+ * @param description - The description of the project
173
+ * @param repoUrl - The repository url
174
+ * @param destPath - The path where the project is located
175
+ */
176
+ export async function createShapeTemplate(
177
+ name: string,
178
+ description: string,
179
+ repoUrl: string,
180
+ destPath: string,
181
+ ): Promise<void> {
182
+ const sourcePath = path.join(__dirname, "..", "..", "files", "create-shape");
183
+
184
+ await copyEmptyTemplateFiles(destPath);
185
+
186
+ await cp(sourcePath, destPath, {
187
+ recursive: true,
188
+ force: true,
189
+ filter: copyFilter,
190
+ });
191
+
192
+ await updateIndexFile(destPath, name);
193
+ await updateShapePackageFile(destPath, name, description, repoUrl);
194
+ await updateShapePackageDistFile(destPath, name, description, repoUrl);
195
+ await updateReadmeFile(destPath, name, description, repoUrl);
196
+ await updateShapeWebpackFile(destPath, name, description);
197
+
198
+ await runInstall(destPath);
199
+ await runBuild(destPath);
200
+ }