@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.
- package/.cache/eslint/.eslintcache +1 -0
- package/.dependency-cruiser.cjs +382 -0
- package/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/create.d.ts +3 -0
- package/dist/create.js +10 -0
- package/dist/plugin/create-plugin.d.ts +8 -0
- package/dist/plugin/create-plugin.js +136 -0
- package/dist/plugin/plugin.d.ts +3 -0
- package/dist/plugin/plugin.js +34 -0
- package/dist/preset/create-preset.d.ts +8 -0
- package/dist/preset/create-preset.js +154 -0
- package/dist/preset/preset.d.ts +3 -0
- package/dist/preset/preset.js +34 -0
- package/dist/shape/create-shape.d.ts +8 -0
- package/dist/shape/create-shape.js +137 -0
- package/dist/shape/shape.d.ts +3 -0
- package/dist/shape/shape.js +34 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/eslint.config.js +22 -0
- package/files/create-plugin/README.md +74 -0
- package/files/create-plugin/src/PluginInstance.ts +18 -0
- package/files/create-plugin/src/browser.ts +10 -0
- package/files/create-plugin/src/index.lazy.ts +10 -0
- package/files/create-plugin/src/index.ts +9 -0
- package/files/create-plugin/src/plugin.ts +36 -0
- package/files/create-preset/README.md +144 -0
- package/files/create-preset/images/sample.png +0 -0
- package/files/create-preset/src/browser.ts +10 -0
- package/files/create-preset/src/bundle.ts +17 -0
- package/files/create-preset/src/index.lazy.ts +14 -0
- package/files/create-preset/src/index.ts +13 -0
- package/files/create-preset/src/options.ts +6 -0
- package/files/create-shape/README.md +75 -0
- package/files/create-shape/src/ShapeDrawer.ts +16 -0
- package/files/create-shape/src/browser.ts +10 -0
- package/files/create-shape/src/index.lazy.ts +10 -0
- package/files/create-shape/src/index.ts +9 -0
- package/package.json +81 -0
- package/renovate.json +9 -0
- package/src/create.ts +14 -0
- package/src/plugin/create-plugin.ts +198 -0
- package/src/plugin/plugin.ts +46 -0
- package/src/preset/create-preset.ts +218 -0
- package/src/preset/preset.ts +46 -0
- package/src/shape/create-shape.ts +200 -0
- package/src/shape/shape.ts +46 -0
- package/src/tsconfig.json +9 -0
- package/tests/create-plugin.test.ts +40 -0
- package/tests/create-preset.test.ts +40 -0
- package/tests/create-shape.test.ts +40 -0
- package/tests/tsconfig.json +15 -0
- package/tsconfig.json +53 -0
- 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: ``,
|
|
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: ``,
|
|
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: ``,
|
|
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
|
+
}
|