servcraft 0.4.8 → 0.4.9
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/ROADMAP.md +2 -1
- package/dist/cli/index.cjs +102 -24
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +102 -24
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/add-module.ts +111 -6
- package/src/cli/commands/init.ts +77 -20
package/dist/cli/index.js
CHANGED
|
@@ -1928,7 +1928,7 @@ async function findServercraftModules() {
|
|
|
1928
1928
|
}
|
|
1929
1929
|
return null;
|
|
1930
1930
|
}
|
|
1931
|
-
async function generateModuleFiles(moduleName, moduleDir) {
|
|
1931
|
+
async function generateModuleFiles(moduleName, moduleDir, language = "typescript", moduleSystem = "esm", fileExtension = "ts") {
|
|
1932
1932
|
const moduleNameMap = {
|
|
1933
1933
|
users: "user",
|
|
1934
1934
|
"rate-limit": "rate-limit",
|
|
@@ -1941,7 +1941,8 @@ async function generateModuleFiles(moduleName, moduleDir) {
|
|
|
1941
1941
|
if (servercraftModulesDir) {
|
|
1942
1942
|
const sourceModuleDir = path5.join(servercraftModulesDir, sourceDirName);
|
|
1943
1943
|
if (await fileExists(sourceModuleDir)) {
|
|
1944
|
-
|
|
1944
|
+
const jsExt = language === "javascript" ? fileExtension : "js";
|
|
1945
|
+
await copyModuleFromSource(sourceModuleDir, moduleDir, language, moduleSystem, jsExt);
|
|
1945
1946
|
return;
|
|
1946
1947
|
}
|
|
1947
1948
|
}
|
|
@@ -1968,16 +1969,48 @@ async function generateModuleFiles(moduleName, moduleDir) {
|
|
|
1968
1969
|
await generateGenericModule(moduleDir, moduleName);
|
|
1969
1970
|
}
|
|
1970
1971
|
}
|
|
1971
|
-
|
|
1972
|
+
function convertESMtoCommonJS(content) {
|
|
1973
|
+
return content.replace(/^export\s+class\s+/gm, "class ").replace(/^export\s+function\s+/gm, "function ").replace(/^export\s+const\s+/gm, "const ").replace(/^export\s+let\s+/gm, "let ").replace(/^export\s+var\s+/gm, "var ").replace(
|
|
1974
|
+
/import\s*\{\s*([^}]+)\s*\}\s*from\s*['"]([^'"]+)['"]/g,
|
|
1975
|
+
"const { $1 } = require('$2')"
|
|
1976
|
+
).replace(/import\s+(\w+)\s+from\s*['"]([^'"]+)['"]/g, "const $1 = require('$2')").replace(
|
|
1977
|
+
/import\s+(\w+)\s*,\s*\{\s*([^}]+)\s*\}\s*from\s*['"]([^'"]+)['"]/g,
|
|
1978
|
+
"const $1 = require('$3');\nconst { $2 } = require('$3')"
|
|
1979
|
+
).replace(/^(class\s+(\w+)\s+\{[\s\S]*?\n\})/gm, "$1\nmodule.exports.$2 = $2;").replace(/export\s*\{\s*([^}]+)\s*\}/g, (match, exports) => {
|
|
1980
|
+
const items = exports.split(",").map((item) => item.trim()).filter(Boolean);
|
|
1981
|
+
return items.map((item) => `module.exports.${item} = ${item};`).join("\n");
|
|
1982
|
+
});
|
|
1983
|
+
}
|
|
1984
|
+
async function copyModuleFromSource(sourceDir, targetDir, language = "typescript", moduleSystem = "esm", fileExtension = "js") {
|
|
1972
1985
|
const entries = await fs4.readdir(sourceDir, { withFileTypes: true });
|
|
1973
1986
|
for (const entry of entries) {
|
|
1974
1987
|
const sourcePath = path5.join(sourceDir, entry.name);
|
|
1975
|
-
|
|
1988
|
+
let targetPath = path5.join(targetDir, entry.name);
|
|
1976
1989
|
if (entry.isDirectory()) {
|
|
1977
1990
|
await fs4.mkdir(targetPath, { recursive: true });
|
|
1978
|
-
await copyModuleFromSource(sourcePath, targetPath);
|
|
1991
|
+
await copyModuleFromSource(sourcePath, targetPath, language, moduleSystem, fileExtension);
|
|
1979
1992
|
} else {
|
|
1980
|
-
|
|
1993
|
+
if (language === "javascript" && entry.name.endsWith(".ts")) {
|
|
1994
|
+
const ext = `.${fileExtension}`;
|
|
1995
|
+
targetPath = targetPath.replace(/\.ts$/, ext);
|
|
1996
|
+
let content = await fs4.readFile(sourcePath, "utf-8");
|
|
1997
|
+
for (let i = 0; i < 3; i++) {
|
|
1998
|
+
content = content.replace(/import\s+type\s+\{[^}]+\}\s+from\s+['"][^'"]+['"];?\s*\n/g, "").replace(/import\s+\{([^}]+)\}\s+from/g, (match, imports) => {
|
|
1999
|
+
const filtered = imports.split(",").map((imp) => imp.trim()).filter((imp) => !imp.startsWith("type ")).join(", ");
|
|
2000
|
+
return filtered ? `import {${filtered}} from` : "";
|
|
2001
|
+
}).replace(/from\s+['"](.+?)\.js['"]/g, `from '$1${ext}'`).replace(/\b(private|public|protected|readonly)\s+/g, "").replace(
|
|
2002
|
+
/:\s*[A-Z]\w+(<[^>]+>)?(\[\])?(\s*[|&]\s*[A-Z]\w+(<[^>]+>)?(\[\])?)*(?=[,)\s=\n])/g,
|
|
2003
|
+
""
|
|
2004
|
+
).replace(/(\w+)\s*:\s*[^,)=\n]+([,)])/g, "$1$2").replace(/(\w+)\s*:\s*[^=\n{]+(\s*=)/g, "$1$2").replace(/\)\s*:\s*[^{=\n]+\s*([{=])/g, ") $1").replace(/^export\s+(interface|type)\s+[^;]+;?\s*$/gm, "").replace(/^(interface|type)\s+[^;]+;?\s*$/gm, "").replace(/\s+as\s+\w+/g, "").replace(/<[A-Z][\w,\s<>[\]|&]*>/g, "");
|
|
2005
|
+
}
|
|
2006
|
+
content = content.replace(/^\s*\n/gm, "");
|
|
2007
|
+
if (moduleSystem === "commonjs") {
|
|
2008
|
+
content = convertESMtoCommonJS(content);
|
|
2009
|
+
}
|
|
2010
|
+
await fs4.writeFile(targetPath, content, "utf-8");
|
|
2011
|
+
} else {
|
|
2012
|
+
await fs4.copyFile(sourcePath, targetPath);
|
|
2013
|
+
}
|
|
1981
2014
|
}
|
|
1982
2015
|
}
|
|
1983
2016
|
}
|
|
@@ -2118,13 +2151,13 @@ var initCommand = new Command2("init").alias("new").description("Initialize a ne
|
|
|
2118
2151
|
console.log(chalk6.cyan("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"));
|
|
2119
2152
|
console.log(chalk6.cyan("\u2502") + " " + chalk6.cyan("\u2502"));
|
|
2120
2153
|
console.log(
|
|
2121
|
-
chalk6.cyan("\u2502") +
|
|
2154
|
+
chalk6.cyan("\u2502") + chalk6.bold.white("\u{1F680} Servcraft") + chalk6.gray(" - Project Generator") + " " + chalk6.cyan("\u2502")
|
|
2122
2155
|
);
|
|
2123
2156
|
console.log(
|
|
2124
|
-
chalk6.cyan("\u2502") + "
|
|
2157
|
+
chalk6.cyan("\u2502") + " " + chalk6.gray("by ") + chalk6.blue("Yao Logan") + chalk6.gray(" (@Le-Sourcier)") + " " + chalk6.cyan("\u2502")
|
|
2125
2158
|
);
|
|
2126
2159
|
console.log(
|
|
2127
|
-
chalk6.cyan("\u2502") + "
|
|
2160
|
+
chalk6.cyan("\u2502") + " " + chalk6.bgBlue.white(" in/yao-logan ") + " " + chalk6.cyan("\u2502")
|
|
2128
2161
|
);
|
|
2129
2162
|
console.log(chalk6.cyan("\u2502") + " " + chalk6.cyan("\u2502"));
|
|
2130
2163
|
console.log(chalk6.cyan("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
|
|
@@ -2132,17 +2165,24 @@ var initCommand = new Command2("init").alias("new").description("Initialize a ne
|
|
|
2132
2165
|
let options;
|
|
2133
2166
|
if (cmdOptions?.yes) {
|
|
2134
2167
|
const db = cmdOptions.db || "postgresql";
|
|
2168
|
+
const language = cmdOptions.javascript ? "javascript" : "typescript";
|
|
2169
|
+
const moduleSystem = cmdOptions.commonjs ? "commonjs" : "esm";
|
|
2170
|
+
let fileExtension = "ts";
|
|
2171
|
+
if (language === "javascript") {
|
|
2172
|
+
fileExtension = moduleSystem === "commonjs" ? "cjs" : "js";
|
|
2173
|
+
}
|
|
2135
2174
|
options = {
|
|
2136
2175
|
name: name || "my-servcraft-app",
|
|
2137
|
-
language
|
|
2138
|
-
moduleSystem
|
|
2176
|
+
language,
|
|
2177
|
+
moduleSystem,
|
|
2178
|
+
fileExtension,
|
|
2139
2179
|
database: db,
|
|
2140
2180
|
orm: db === "mongodb" ? "mongoose" : db === "none" ? "none" : "prisma",
|
|
2141
2181
|
validator: "zod",
|
|
2142
2182
|
features: ["auth", "users", "email"]
|
|
2143
2183
|
};
|
|
2144
2184
|
} else {
|
|
2145
|
-
const
|
|
2185
|
+
const basicAnswers = await inquirer2.prompt([
|
|
2146
2186
|
{
|
|
2147
2187
|
type: "input",
|
|
2148
2188
|
name: "name",
|
|
@@ -2164,17 +2204,43 @@ var initCommand = new Command2("init").alias("new").description("Initialize a ne
|
|
|
2164
2204
|
{ name: " JavaScript", value: "javascript" }
|
|
2165
2205
|
],
|
|
2166
2206
|
default: "typescript"
|
|
2167
|
-
}
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2207
|
+
}
|
|
2208
|
+
]);
|
|
2209
|
+
let moduleSystem = "esm";
|
|
2210
|
+
let fileExtension = "ts";
|
|
2211
|
+
if (basicAnswers.language === "javascript") {
|
|
2212
|
+
const jsConfigAnswers = await inquirer2.prompt([
|
|
2213
|
+
{
|
|
2214
|
+
type: "list",
|
|
2215
|
+
name: "moduleSystem",
|
|
2216
|
+
message: "\u{1F4E6} Select module syntax:",
|
|
2217
|
+
choices: [
|
|
2218
|
+
{ name: "\u2728 ESM (import/export)", value: "esm" },
|
|
2219
|
+
{ name: " CommonJS (require/module.exports)", value: "commonjs" }
|
|
2220
|
+
],
|
|
2221
|
+
default: "esm"
|
|
2222
|
+
},
|
|
2223
|
+
{
|
|
2224
|
+
type: "list",
|
|
2225
|
+
name: "fileExtension",
|
|
2226
|
+
message: "\u{1F4C4} Select file extension:",
|
|
2227
|
+
choices: (answers2) => {
|
|
2228
|
+
if (answers2.moduleSystem === "esm") {
|
|
2229
|
+
return [{ name: "\u2728 .js (standard for ESM)", value: "js" }];
|
|
2230
|
+
} else {
|
|
2231
|
+
return [
|
|
2232
|
+
{ name: "\u2728 .cjs (explicit CommonJS)", value: "cjs" },
|
|
2233
|
+
{ name: " .js (CommonJS in .js)", value: "js" }
|
|
2234
|
+
];
|
|
2235
|
+
}
|
|
2236
|
+
},
|
|
2237
|
+
default: (answers2) => answers2.moduleSystem === "esm" ? "js" : "cjs"
|
|
2238
|
+
}
|
|
2239
|
+
]);
|
|
2240
|
+
moduleSystem = jsConfigAnswers.moduleSystem;
|
|
2241
|
+
fileExtension = jsConfigAnswers.fileExtension;
|
|
2242
|
+
}
|
|
2243
|
+
const restAnswers = await inquirer2.prompt([
|
|
2178
2244
|
{
|
|
2179
2245
|
type: "list",
|
|
2180
2246
|
name: "database",
|
|
@@ -2213,6 +2279,12 @@ var initCommand = new Command2("init").alias("new").description("Initialize a ne
|
|
|
2213
2279
|
]
|
|
2214
2280
|
}
|
|
2215
2281
|
]);
|
|
2282
|
+
const answers = {
|
|
2283
|
+
...basicAnswers,
|
|
2284
|
+
moduleSystem,
|
|
2285
|
+
fileExtension,
|
|
2286
|
+
...restAnswers
|
|
2287
|
+
};
|
|
2216
2288
|
const db = answers.database;
|
|
2217
2289
|
options = {
|
|
2218
2290
|
...answers,
|
|
@@ -2318,7 +2390,13 @@ var initCommand = new Command2("init").alias("new").description("Initialize a ne
|
|
|
2318
2390
|
moduleSpinner.text = `Installing ${feature} module...`;
|
|
2319
2391
|
const moduleDir = path6.join(projectDir, "src/modules", feature);
|
|
2320
2392
|
await ensureDir(moduleDir);
|
|
2321
|
-
await generateModuleFiles(
|
|
2393
|
+
await generateModuleFiles(
|
|
2394
|
+
feature,
|
|
2395
|
+
moduleDir,
|
|
2396
|
+
options.language,
|
|
2397
|
+
options.moduleSystem,
|
|
2398
|
+
options.fileExtension
|
|
2399
|
+
);
|
|
2322
2400
|
}
|
|
2323
2401
|
moduleSpinner.succeed(`${options.features.length} module(s) installed!`);
|
|
2324
2402
|
} catch (err) {
|