@tsparticles/cli 1.6.5 → 1.8.0
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/dist/build/build-eslint.js +1 -1
- package/dist/build/build-prettier.js +10 -10
- package/dist/create/create.js +4 -0
- package/dist/create/plugin/create-plugin.js +86 -0
- package/dist/create/plugin/plugin.js +58 -0
- package/dist/create/shape/create-shape.js +86 -0
- package/dist/create/shape/shape.js +58 -0
- package/dist/utils/template-utils.js +1 -4
- package/files/create-plugin/README.md +74 -0
- package/files/create-plugin/src/PluginInstance.ts +15 -0
- package/files/create-plugin/src/index.ts +39 -0
- package/files/create-preset/README.md +30 -26
- package/files/create-shape/README.md +75 -0
- package/files/create-shape/src/ShapeDrawer.ts +19 -0
- package/files/create-shape/src/index.ts +9 -0
- package/files/empty-project/package.json +8 -8
- package/files/empty-project/webpack.config.js +1 -1
- package/package.json +14 -15
- package/src/build/build-eslint.ts +2 -2
- package/src/build/build-prettier.ts +10 -10
- package/src/build/build.ts +2 -2
- package/src/create/create.ts +5 -0
- package/src/create/plugin/create-plugin.ts +178 -0
- package/src/create/plugin/plugin.ts +65 -0
- package/src/create/preset/create-preset.ts +11 -11
- package/src/create/shape/create-shape.ts +175 -0
- package/src/create/shape/shape.ts +65 -0
- package/src/utils/template-utils.ts +4 -8
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { camelize, capitalize, dash } from "../../utils/string-utils";
|
|
2
|
+
import {
|
|
3
|
+
copyEmptyTemplateFiles,
|
|
4
|
+
copyFilter,
|
|
5
|
+
runBuild,
|
|
6
|
+
runInstall,
|
|
7
|
+
updatePackageDistFile,
|
|
8
|
+
updatePackageFile,
|
|
9
|
+
updateWebpackFile,
|
|
10
|
+
} from "../../utils/template-utils";
|
|
11
|
+
import fs from "fs-extra";
|
|
12
|
+
import path from "path";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Updates the index file with the correct function name
|
|
16
|
+
* @param destPath - The path where the project is located
|
|
17
|
+
* @param name - The name of the project
|
|
18
|
+
*/
|
|
19
|
+
async function updateIndexFile(destPath: string, name: string): Promise<void> {
|
|
20
|
+
const indexPath = path.resolve(destPath, "src", "index.ts"),
|
|
21
|
+
index = await fs.readFile(indexPath, "utf-8"),
|
|
22
|
+
capitalizedName = capitalize(capitalize(name, "-"), " "),
|
|
23
|
+
camelizedName = camelize(capitalizedName),
|
|
24
|
+
indexFunctionRegex = /loadTemplateShape/g,
|
|
25
|
+
replacedFuncText = index.replace(indexFunctionRegex, `load${capitalizedName}Shape`),
|
|
26
|
+
indexNameRegex = /"#template#"/g,
|
|
27
|
+
replacedNameText = replacedFuncText.replace(indexNameRegex, `"${camelizedName}"`);
|
|
28
|
+
|
|
29
|
+
await fs.writeFile(indexPath, replacedNameText);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Updates the shape package file
|
|
34
|
+
* @param destPath - The path where the project is located
|
|
35
|
+
* @param name - The name of the project
|
|
36
|
+
* @param description - The description of the project
|
|
37
|
+
* @param repoUrl - The repository url
|
|
38
|
+
*/
|
|
39
|
+
async function updateShapePackageFile(
|
|
40
|
+
destPath: string,
|
|
41
|
+
name: string,
|
|
42
|
+
description: string,
|
|
43
|
+
repoUrl: string,
|
|
44
|
+
): Promise<void> {
|
|
45
|
+
const camelizedName = camelize(camelize(name, "-"), " "),
|
|
46
|
+
dashedName = dash(camelizedName);
|
|
47
|
+
|
|
48
|
+
updatePackageFile(
|
|
49
|
+
destPath,
|
|
50
|
+
`"tsparticles-shape-${dashedName}"`,
|
|
51
|
+
description,
|
|
52
|
+
`"tsparticles.shape.${camelizedName}.min.js"`,
|
|
53
|
+
repoUrl,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Updates the shape package dist 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 updateShapePackageDistFile(
|
|
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
|
+
updatePackageDistFile(
|
|
74
|
+
destPath,
|
|
75
|
+
`"tsparticles-shape-${dashedName}"`,
|
|
76
|
+
description,
|
|
77
|
+
`"tsparticles.shape.${camelizedName}.min.js"`,
|
|
78
|
+
repoUrl,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Updates the shape readme 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 updateReadmeFile(destPath: string, name: string, description: string, repoUrl: string): Promise<void> {
|
|
90
|
+
const readmePath = path.resolve(destPath, "README.md"),
|
|
91
|
+
readme = await fs.readFile(readmePath, "utf-8"),
|
|
92
|
+
capitalizedName = capitalize(capitalize(name, "-"), " "),
|
|
93
|
+
camelizedName = camelize(capitalizedName),
|
|
94
|
+
dashedName = dash(camelizedName),
|
|
95
|
+
readmeDescriptionRegex = /tsParticles Template Shape/g,
|
|
96
|
+
replacedDescriptionText = readme.replace(readmeDescriptionRegex, `tsParticles ${description} Shape`),
|
|
97
|
+
readmePackageNameRegex = /tsparticles-shape-template/g,
|
|
98
|
+
replacedPackageNameText = replacedDescriptionText.replace(
|
|
99
|
+
readmePackageNameRegex,
|
|
100
|
+
`tsparticles-shape-${dashedName}`,
|
|
101
|
+
),
|
|
102
|
+
readmeFileNameRegex = /tsparticles\.shape\.template(\.bundle)?\.min\.js/g,
|
|
103
|
+
replacedFileNameText = replacedPackageNameText.replace(
|
|
104
|
+
readmeFileNameRegex,
|
|
105
|
+
`tsparticles.shape.${camelizedName}$1.min.js`,
|
|
106
|
+
),
|
|
107
|
+
readmeFunctionNameRegex = /loadTemplateShape/g,
|
|
108
|
+
replacedFunctionNameText = replacedFileNameText.replace(readmeFunctionNameRegex, `load${capitalizedName}Shape`),
|
|
109
|
+
readmeMiniDescriptionRegex =
|
|
110
|
+
/\[tsParticles]\(https:\/\/github.com\/matteobruni\/tsparticles\) additional template shape\./g,
|
|
111
|
+
replacedMiniDescriptionText = replacedFunctionNameText.replace(
|
|
112
|
+
readmeMiniDescriptionRegex,
|
|
113
|
+
`[tsParticles](https://github.com/matteobruni/tsparticles) additional ${name} shape.`,
|
|
114
|
+
),
|
|
115
|
+
readmeUsageRegex = /shape\.type: "template"/g,
|
|
116
|
+
replacedUsageText = replacedMiniDescriptionText.replace(readmeUsageRegex, `shape.type: "${camelizedName}`),
|
|
117
|
+
sampleImageRegex =
|
|
118
|
+
/!\[demo]\(https:\/\/raw.githubusercontent.com\/tsparticles\/shape-template\/main\/images\/sample.png\)/g,
|
|
119
|
+
repoPath = repoUrl.includes("github.com")
|
|
120
|
+
? repoUrl.substring(repoUrl.indexOf("github.com/") + 11, repoUrl.indexOf(".git"))
|
|
121
|
+
: "tsparticles/shape-template",
|
|
122
|
+
replacedText = replacedUsageText.replace(
|
|
123
|
+
sampleImageRegex,
|
|
124
|
+
``,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
await fs.writeFile(readmePath, replacedText);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Updates the shape webpack file
|
|
132
|
+
* @param destPath - The path where the project is located
|
|
133
|
+
* @param name - The name of the project
|
|
134
|
+
* @param description - The description of the project
|
|
135
|
+
*/
|
|
136
|
+
async function updateShapeWebpackFile(destPath: string, name: string, description: string): Promise<void> {
|
|
137
|
+
await updateWebpackFile(
|
|
138
|
+
destPath,
|
|
139
|
+
camelize(capitalize(capitalize(name, "-"), " ")),
|
|
140
|
+
`tsParticles ${description} Shape`,
|
|
141
|
+
"loadParticlesShape",
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates the shape project
|
|
147
|
+
* @param name - The name of the project
|
|
148
|
+
* @param description - The description of the project
|
|
149
|
+
* @param repoUrl - The repository url
|
|
150
|
+
* @param destPath - The path where the project is located
|
|
151
|
+
*/
|
|
152
|
+
export async function createShapeTemplate(
|
|
153
|
+
name: string,
|
|
154
|
+
description: string,
|
|
155
|
+
repoUrl: string,
|
|
156
|
+
destPath: string,
|
|
157
|
+
): Promise<void> {
|
|
158
|
+
const sourcePath = path.resolve(__dirname, "..", "..", "..", "files", "create-shape");
|
|
159
|
+
|
|
160
|
+
await copyEmptyTemplateFiles(destPath);
|
|
161
|
+
|
|
162
|
+
await fs.copy(sourcePath, destPath, {
|
|
163
|
+
overwrite: true,
|
|
164
|
+
filter: copyFilter,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
await updateIndexFile(destPath, name);
|
|
168
|
+
await updateShapePackageFile(destPath, name, description, repoUrl);
|
|
169
|
+
await updateShapePackageDistFile(destPath, name, description, repoUrl);
|
|
170
|
+
await updateReadmeFile(destPath, name, description, repoUrl);
|
|
171
|
+
await updateShapeWebpackFile(destPath, name, description);
|
|
172
|
+
|
|
173
|
+
runInstall(destPath);
|
|
174
|
+
runBuild(destPath);
|
|
175
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import prompts, { type PromptObject } from "prompts";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { capitalize } from "../../utils/string-utils";
|
|
4
|
+
import { createShapeTemplate } from "./create-shape";
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
import fs from "fs-extra";
|
|
7
|
+
import path from "path";
|
|
8
|
+
|
|
9
|
+
const shapeCommand = new Command("shape");
|
|
10
|
+
|
|
11
|
+
shapeCommand.description("Create a new tsParticles shape");
|
|
12
|
+
shapeCommand.argument("<destination>", "Destination folder");
|
|
13
|
+
shapeCommand.action(async (destination: string) => {
|
|
14
|
+
let repoUrl: string;
|
|
15
|
+
|
|
16
|
+
const destPath = path.resolve(path.join(process.cwd(), destination)),
|
|
17
|
+
destExists = await fs.pathExists(destPath);
|
|
18
|
+
|
|
19
|
+
if (destExists) {
|
|
20
|
+
const destContents = await fs.readdir(destPath),
|
|
21
|
+
destContentsNoGit = destContents.filter(t => t !== ".git" && t !== ".gitignore");
|
|
22
|
+
|
|
23
|
+
if (destContentsNoGit.length) {
|
|
24
|
+
throw new Error("Destination folder already exists and is not empty");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
await fs.ensureDir(destPath);
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
repoUrl = execSync("git config --get remote.origin.url").toString();
|
|
32
|
+
} catch {
|
|
33
|
+
repoUrl = "";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const initialName = destPath.split(path.sep).pop(),
|
|
37
|
+
questions: PromptObject[] = [
|
|
38
|
+
{
|
|
39
|
+
type: "text",
|
|
40
|
+
name: "name",
|
|
41
|
+
message: "What is the name of the shape?",
|
|
42
|
+
validate: (value: string) => (value ? true : "The name can't be empty"),
|
|
43
|
+
initial: initialName,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: "text",
|
|
47
|
+
name: "description",
|
|
48
|
+
message: "What is the description of the shape?",
|
|
49
|
+
validate: (value: string) => (value ? true : "The description can't be empty"),
|
|
50
|
+
initial: capitalize(initialName || ""),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: "text",
|
|
54
|
+
name: "repositoryUrl",
|
|
55
|
+
message: "What is the repository URL? (optional)",
|
|
56
|
+
initial: repoUrl.trim(),
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const { name, description, repositoryUrl } = await prompts(questions);
|
|
61
|
+
|
|
62
|
+
createShapeTemplate(name.trim(), description.trim(), repositoryUrl.trim(), destPath);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export { shapeCommand };
|
|
@@ -15,7 +15,7 @@ export async function updatePackageFile(
|
|
|
15
15
|
packageName: string,
|
|
16
16
|
description: string,
|
|
17
17
|
fileName: string,
|
|
18
|
-
repoUrl: string
|
|
18
|
+
repoUrl: string,
|
|
19
19
|
): Promise<void> {
|
|
20
20
|
const packagePath = path.resolve(destPath, "package.json"),
|
|
21
21
|
packageContents = await fs.readFile(packagePath, "utf-8"),
|
|
@@ -48,7 +48,7 @@ export async function updatePackageDistFile(
|
|
|
48
48
|
packageName: string,
|
|
49
49
|
description: string,
|
|
50
50
|
fileName: string,
|
|
51
|
-
repoUrl: string
|
|
51
|
+
repoUrl: string,
|
|
52
52
|
): Promise<void> {
|
|
53
53
|
const packagePath = path.resolve(destPath, "package.dist.json"),
|
|
54
54
|
packageContents = await fs.readFile(packagePath, "utf-8"),
|
|
@@ -79,7 +79,7 @@ export async function updateWebpackFile(
|
|
|
79
79
|
destPath: string,
|
|
80
80
|
name: string,
|
|
81
81
|
description: string,
|
|
82
|
-
fnName: string
|
|
82
|
+
fnName: string,
|
|
83
83
|
): Promise<void> {
|
|
84
84
|
const webpackPath = path.resolve(destPath, "webpack.config.js"),
|
|
85
85
|
webpack = await fs.readFile(webpackPath, "utf-8"),
|
|
@@ -112,11 +112,7 @@ export async function copyEmptyTemplateFiles(destPath: string): Promise<void> {
|
|
|
112
112
|
* @returns true if the file should be copied
|
|
113
113
|
*/
|
|
114
114
|
export function copyFilter(src: string): boolean {
|
|
115
|
-
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return true;
|
|
115
|
+
return !(src.endsWith("node_modules") || src.endsWith("dist"));
|
|
120
116
|
}
|
|
121
117
|
|
|
122
118
|
/**
|