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/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
- await copyModuleFromSource(sourceModuleDir, moduleDir);
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
- async function copyModuleFromSource(sourceDir, targetDir) {
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
- const targetPath = path5.join(targetDir, entry.name);
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
- await fs4.copyFile(sourcePath, targetPath);
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") + " " + chalk6.bold.white("\u{1F680} Servcraft") + chalk6.gray(" - Project Generator") + " " + 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") + " " + chalk6.gray("by ") + chalk6.blue("Yao Logan") + chalk6.gray(" (@Le-Sourcier)") + " " + 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") + " " + chalk6.bgBlue.white(" in/yao-logan ") + " " + 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: cmdOptions.javascript ? "javascript" : "typescript",
2138
- moduleSystem: cmdOptions.commonjs ? "commonjs" : "esm",
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 answers = await inquirer2.prompt([
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
- type: "list",
2170
- name: "moduleSystem",
2171
- message: "\u{1F4E6} Select module system:",
2172
- choices: [
2173
- { name: "\u2728 ESM (import/export) - Recommended", value: "esm" },
2174
- { name: " CommonJS (require/module.exports)", value: "commonjs" }
2175
- ],
2176
- default: "esm"
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(feature, moduleDir);
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) {