fwinit 1.0.1 → 1.0.3

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 (2) hide show
  1. package/dist/index.js +116 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -47,8 +47,8 @@ function findTemplate(input) {
47
47
 
48
48
  // src/downloader.ts
49
49
  import AdmZip from "adm-zip";
50
- import { mkdir, rm, cp, readdir } from "fs/promises";
51
- import { join } from "path";
50
+ import { mkdir, rm, cp, readdir, readFile, writeFile, rename } from "fs/promises";
51
+ import { join, extname } from "path";
52
52
  import { tmpdir } from "os";
53
53
  import { randomBytes } from "crypto";
54
54
  var GITHUB_REPO = "orlandotellez/fwinit";
@@ -101,6 +101,96 @@ async function cleanTemplate(dir) {
101
101
  async function cleanup(tempDir) {
102
102
  await rm(tempDir, { recursive: true, force: true });
103
103
  }
104
+ async function substituteTemplate(dir, projectName, templateFolder) {
105
+ if (templateFolder === "ASPNET") {
106
+ await substituteAspNet(dir, projectName);
107
+ } else {
108
+ await substituteNodejs(dir, projectName);
109
+ }
110
+ }
111
+ async function substituteNodejs(dir, projectName) {
112
+ const packageJsonPath = join(dir, "package.json");
113
+ try {
114
+ const content = await readFile(packageJsonPath, "utf-8");
115
+ const pkg = JSON.parse(content);
116
+ pkg.name = projectName;
117
+ await writeFile(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
118
+ } catch {
119
+ }
120
+ const appJsonPath = join(dir, "app.json");
121
+ try {
122
+ const content = await readFile(appJsonPath, "utf-8");
123
+ const app = JSON.parse(content);
124
+ if (app.expo) {
125
+ app.expo.name = projectName;
126
+ app.expo.slug = projectName;
127
+ if (app.expo.scheme) {
128
+ app.expo.scheme = toScheme(projectName);
129
+ }
130
+ await writeFile(appJsonPath, JSON.stringify(app, null, 2) + "\n");
131
+ }
132
+ } catch {
133
+ }
134
+ }
135
+ function toScheme(str) {
136
+ return str.replace(/[-_\s]+/g, "").toLowerCase();
137
+ }
138
+ async function substituteAspNet(dir, projectName) {
139
+ const pascalName = toPascalCase(projectName);
140
+ const textExtensions = /* @__PURE__ */ new Set([".cs", ".csproj", ".slnx", ".json", ".http"]);
141
+ const allFiles = await getAllFiles(dir);
142
+ for (const filePath of allFiles) {
143
+ const ext = extname(filePath).toLowerCase();
144
+ if (textExtensions.has(ext)) {
145
+ try {
146
+ const content = await readFile(filePath, "utf-8");
147
+ const replaced = content.replace(/Example/g, pascalName);
148
+ if (replaced !== content) {
149
+ await writeFile(filePath, replaced);
150
+ }
151
+ } catch {
152
+ }
153
+ }
154
+ }
155
+ await renameAll(dir, pascalName);
156
+ }
157
+ async function getAllFiles(dir) {
158
+ const results = [];
159
+ const entries = await readdir(dir, { withFileTypes: true });
160
+ for (const entry of entries) {
161
+ const fullPath = join(dir, entry.name);
162
+ if (entry.isDirectory()) {
163
+ results.push(...await getAllFiles(fullPath));
164
+ } else {
165
+ results.push(fullPath);
166
+ }
167
+ }
168
+ return results;
169
+ }
170
+ async function renameAll(dir, pascalName) {
171
+ const entries = await readdir(dir, { withFileTypes: true });
172
+ for (const entry of entries) {
173
+ const oldPath = join(dir, entry.name);
174
+ if (entry.isDirectory()) {
175
+ await renameAll(oldPath, pascalName);
176
+ }
177
+ }
178
+ const entriesAfter = await readdir(dir, { withFileTypes: true });
179
+ for (const entry of entriesAfter) {
180
+ if (entry.name.includes("Example")) {
181
+ const oldPath = join(dir, entry.name);
182
+ const newName = entry.name.replace(/Example/g, pascalName);
183
+ const newPath = join(dir, newName);
184
+ try {
185
+ await rename(oldPath, newPath);
186
+ } catch {
187
+ }
188
+ }
189
+ }
190
+ }
191
+ function toPascalCase(str) {
192
+ return str.split(/[-_\s]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
193
+ }
104
194
 
105
195
  // src/prompts.ts
106
196
  import inquirer from "inquirer";
@@ -109,7 +199,7 @@ async function selectTemplate() {
109
199
  {
110
200
  type: "list",
111
201
  name: "template",
112
- message: "What project do you want to create?",
202
+ message: "\xBFQu\xE9 proyecto quer\xE9s crear?",
113
203
  choices: TEMPLATES.map((t) => ({
114
204
  name: `${t.name} \u2014 ${t.description}`,
115
205
  value: t
@@ -123,11 +213,11 @@ async function askProjectName() {
123
213
  {
124
214
  type: "input",
125
215
  name: "name",
126
- message: "Project name:",
216
+ message: "Nombre del proyecto:",
127
217
  validate: (input) => {
128
- if (!input.trim()) return "Name cannot be empty";
218
+ if (!input.trim()) return "El nombre no puede estar vac\xEDo";
129
219
  if (!/^[a-zA-Z0-9_-]+$/.test(input)) {
130
- return "Only letters, numbers, hyphens and underscores";
220
+ return "Solo letras, n\xFAmeros, guiones y guiones bajos";
131
221
  }
132
222
  return true;
133
223
  }
@@ -149,10 +239,10 @@ function printSuccess(projectName, templateName, postInit) {
149
239
  const installCmd = postInit?.install || "npm install";
150
240
  const devCmd = postInit?.dev || "npm run dev";
151
241
  console.log(`
152
- \x1B[32m\u2714\x1B[0m Template downloaded
153
- \x1B[32m\u2714\x1B[0m Project created in ./${projectName}
242
+ \x1B[32m\u2714\x1B[0m Template descargado
243
+ \x1B[32m\u2714\x1B[0m Proyecto creado en ./${projectName}
154
244
 
155
- \x1B[1mNext steps:\x1B[0m
245
+ \x1B[1mPr\xF3ximos pasos:\x1B[0m
156
246
 
157
247
  \x1B[36mcd ${projectName}\x1B[0m
158
248
  \x1B[36m${installCmd}\x1B[0m
@@ -162,10 +252,10 @@ function printSuccess(projectName, templateName, postInit) {
162
252
 
163
253
  // src/index.ts
164
254
  var program = new Command();
165
- program.name("fwinit").description("CLI to create projects from templates").version("1.0.0");
166
- program.command("list").description("Show available templates").action(() => {
255
+ program.name("fwinit").description("CLI para crear proyectos desde templates").version("1.0.0");
256
+ program.command("list").description("Mostrar templates disponibles").action(() => {
167
257
  console.log(
168
- chalk.bold("\nAvailable templates:\n")
258
+ chalk.bold("\nTemplates disponibles:\n")
169
259
  );
170
260
  TEMPLATES.forEach((t) => {
171
261
  console.log(
@@ -174,7 +264,7 @@ program.command("list").description("Show available templates").action(() => {
174
264
  });
175
265
  console.log();
176
266
  });
177
- program.argument("[template]", "Template to use").argument("[project-name]", "Project name").action(
267
+ program.argument("[template]", "Template a usar").argument("[project-name]", "Nombre del proyecto").action(
178
268
  async (templateArg, projectNameArg) => {
179
269
  try {
180
270
  let template = templateArg ? findTemplate(templateArg) : void 0;
@@ -183,11 +273,11 @@ program.argument("[template]", "Template to use").argument("[project-name]", "Pr
183
273
  console.error(
184
274
  chalk.red(
185
275
  `
186
- \u2716 Template "${templateArg}" not found.
276
+ \u2716 Template "${templateArg}" no encontrado.
187
277
  `
188
278
  )
189
279
  );
190
- console.log("Available templates:");
280
+ console.log("Templates disponibles:");
191
281
  TEMPLATES.forEach(
192
282
  (t) => console.log(` - ${t.folder.toLowerCase()}`)
193
283
  );
@@ -203,28 +293,33 @@ program.argument("[template]", "Template to use").argument("[project-name]", "Pr
203
293
  console.error(
204
294
  chalk.red(
205
295
  `
206
- \u2716 Directory "${projectName}" already exists.`
296
+ \u2716 El directorio "${projectName}" ya existe.`
207
297
  )
208
298
  );
209
299
  process.exit(1);
210
300
  }
211
301
  const spinner = ora(
212
- `Downloading ${template.name} template...`
302
+ `Descargando template ${template.name}...`
213
303
  ).start();
214
304
  const { tempDir, templatePath } = await downloadAndExtract(template.folder);
215
- spinner.text = "Creating project...";
305
+ spinner.text = "Creando proyecto...";
216
306
  await copyTemplate(
217
307
  templatePath,
218
308
  getProjectPath(projectName)
219
309
  );
310
+ await substituteTemplate(
311
+ getProjectPath(projectName),
312
+ projectName,
313
+ template.folder
314
+ );
220
315
  await cleanup(tempDir);
221
- spinner.succeed("Template downloaded");
316
+ spinner.succeed("Template descargado");
222
317
  let postInit;
223
318
  try {
224
- const { readFile } = await import("fs/promises");
319
+ const { readFile: readFile2 } = await import("fs/promises");
225
320
  const { join: join2 } = await import("path");
226
321
  const tj = JSON.parse(
227
- await readFile(
322
+ await readFile2(
228
323
  join2(getProjectPath(projectName), "template.json"),
229
324
  "utf-8"
230
325
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fwinit",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "CLI para crear proyectos desde templates",
5
5
  "type": "module",
6
6
  "bin": {