create-jilatax 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -17,8 +17,9 @@ cd my-app
17
17
  bun run run:android
18
18
  ```
19
19
 
20
- The creator asks for the application name, Android package ID, and whether to
21
- install dependencies. In non-interactive environments, pass the directory and
20
+ The creator derives the application name from the project directory, then asks
21
+ for the Android package ID and whether to install dependencies. Installation is
22
+ disabled by default. In non-interactive environments, pass the directory and
22
23
  options explicitly:
23
24
 
24
25
  ```bash
package/dist/bin.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  //#region src/bin.ts
3
- require("./cli-DD2gvmMZ.cjs").runCreateCli().then((exitCode) => {
3
+ require("./cli-DE3ovkQR.cjs").runCreateCli().then((exitCode) => {
4
4
  process.exitCode = exitCode;
5
5
  });
6
6
  //#endregion
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as runCreateCli } from "./cli-DLBJ0XnY.js";
2
+ import { n as runCreateCli } from "./cli-Bd5vJvDf.js";
3
3
  //#region src/bin.ts
4
4
  runCreateCli().then((exitCode) => {
5
5
  process.exitCode = exitCode;
@@ -1,8 +1,9 @@
1
1
  import * as prompts from "@clack/prompts";
2
2
  import { chmod, copyFile, lstat, mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import path from "node:path";
3
5
  import { stdin, stdout } from "node:process";
4
6
  import { spawn } from "node:child_process";
5
- import path from "node:path";
6
7
  import { fileURLToPath } from "node:url";
7
8
  import { parseAppConfig, syncAndroidProjectConfig } from "jilatax";
8
9
  //#region src/generator.ts
@@ -39,7 +40,7 @@ async function createProject(options) {
39
40
  throw error;
40
41
  }
41
42
  const shouldInstall = options.install === true;
42
- if (shouldInstall) await (options.installer ?? installWithBun)(projectDirectory);
43
+ if (shouldInstall) await (options.installer ?? ((directory) => installWithBun(directory, options.silentInstall === true)))(projectDirectory);
43
44
  return {
44
45
  displayName,
45
46
  installed: shouldInstall,
@@ -194,12 +195,12 @@ async function assertTargetDoesNotExist(target) {
194
195
  function titleCase$1(value) {
195
196
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
196
197
  }
197
- function installWithBun(projectDirectory) {
198
+ function installWithBun(projectDirectory, silent) {
198
199
  return new Promise((resolveInstall, rejectInstall) => {
199
200
  const child = spawn("bun", ["install"], {
200
201
  cwd: projectDirectory,
201
202
  env: process.env,
202
- stdio: "inherit",
203
+ stdio: silent ? "ignore" : "inherit",
203
204
  windowsHide: true
204
205
  });
205
206
  child.once("error", rejectInstall);
@@ -228,13 +229,25 @@ async function runCreateCli(args = process.argv.slice(2), services = {}) {
228
229
  log(await readCreatorVersion());
229
230
  return 0;
230
231
  }
231
- const options = services.interactive ?? (stdin.isTTY && stdout.isTTY) ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
232
- printResult(await (services.create ?? createProject)({
233
- displayName: options.displayName,
234
- install: options.install,
235
- packageId: options.packageId,
236
- targetDirectory: options.targetDirectory
237
- }), log);
232
+ const interactive = services.interactive ?? (stdin.isTTY && stdout.isTTY);
233
+ const options = interactive ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
234
+ const generate = services.create ?? createProject;
235
+ const progress = interactive && options.install ? startInstallProgress() : void 0;
236
+ let result;
237
+ try {
238
+ result = await generate({
239
+ displayName: options.displayName,
240
+ install: options.install,
241
+ packageId: options.packageId,
242
+ ...progress === void 0 ? {} : { silentInstall: true },
243
+ targetDirectory: options.targetDirectory
244
+ });
245
+ } catch (error) {
246
+ progress?.fail();
247
+ throw error;
248
+ }
249
+ progress?.succeed();
250
+ printResult(result, log, interactive);
238
251
  return 0;
239
252
  } catch (error) {
240
253
  if (error instanceof PromptCancelledError) return 0;
@@ -292,7 +305,7 @@ function parseArgs(args) {
292
305
  };
293
306
  }
294
307
  async function promptForOptions(options) {
295
- prompts.intro("Jilatax · Android-first Lynx application");
308
+ printWelcome(await readCreatorVersion());
296
309
  const targetDirectory = options.targetDirectory ?? unwrapPrompt(await prompts.text({
297
310
  message: "Where should the project be created?",
298
311
  placeholder: "./my-jilatax-app",
@@ -305,17 +318,7 @@ async function promptForOptions(options) {
305
318
  }
306
319
  }));
307
320
  const projectName = normalizeProjectNameFromDirectory(targetDirectory);
308
- const displayName = options.displayName ?? unwrapPrompt(await prompts.text({
309
- initialValue: titleCase(projectName),
310
- message: "Application name",
311
- validate(value) {
312
- try {
313
- normalizeDisplayName(value ?? "");
314
- } catch (error) {
315
- return validationMessage(error);
316
- }
317
- }
318
- }));
321
+ const displayName = options.displayName ?? titleCase(projectName);
319
322
  const packageId = options.packageId ?? unwrapPrompt(await prompts.text({
320
323
  initialValue: defaultPackageId(projectName),
321
324
  message: "Android application ID",
@@ -328,7 +331,7 @@ async function promptForOptions(options) {
328
331
  }
329
332
  }));
330
333
  const install = options.install ?? unwrapPrompt(await prompts.confirm({
331
- initialValue: true,
334
+ initialValue: false,
332
335
  message: "Install dependencies with Bun?"
333
336
  }));
334
337
  return {
@@ -374,16 +377,98 @@ function readInlineValue(argument, option) {
374
377
  function titleCase(value) {
375
378
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
376
379
  }
377
- function printResult(result, log) {
378
- const installStep = result.installed ? "" : " bun install\n";
379
- log(`Created ${result.displayName} in ${result.projectDirectory}.
380
-
381
- Next steps:
382
- cd ${JSON.stringify(result.projectDirectory)}
383
- ${installStep} bun run run:android
384
-
385
- Release bundle:
386
- bun run create:aab`);
380
+ function printWelcome(version) {
381
+ const reset = "\x1B[0m";
382
+ const cyan = "\x1B[36m";
383
+ const brightCyan = "\x1B[96m";
384
+ const green = "\x1B[32m";
385
+ const bold = "\x1B[1m";
386
+ const dim = "\x1B[2m";
387
+ const mascot = [`${cyan}╲╲_${brightCyan}╱╱${reset}`, `${cyan}(${green}●${cyan}▽${green}●${cyan})${reset}`];
388
+ const welcome = [`${bold}${brightCyan}JILATAX${reset} ${dim}v${version}${reset}`, `${dim}Welcome.${reset} Build your next Android-first app.`];
389
+ console.log(`${mascot.map((line, index) => `${line} ${welcome[index]}`).join("\n")}\n`);
390
+ }
391
+ function startInstallProgress() {
392
+ const reset = "\x1B[0m";
393
+ const cyan = "\x1B[36m";
394
+ const dim = "\x1B[2m";
395
+ const green = "\x1B[32m";
396
+ const frames = [
397
+ [
398
+ 45,
399
+ 105,
400
+ 44,
401
+ 46
402
+ ],
403
+ [
404
+ 105,
405
+ 44,
406
+ 46,
407
+ 45
408
+ ],
409
+ [
410
+ 44,
411
+ 46,
412
+ 45,
413
+ 105
414
+ ],
415
+ [
416
+ 46,
417
+ 45,
418
+ 105,
419
+ 44
420
+ ]
421
+ ];
422
+ let frameIndex = 0;
423
+ const renderBar = () => {
424
+ const colors = frames[frameIndex % frames.length] ?? frames[0];
425
+ frameIndex += 1;
426
+ return `${colors.map((color) => `\u001B[${color}m `).join("")}${reset}`;
427
+ };
428
+ const renderTitle = () => `${renderBar()} Project initializing...`;
429
+ stdout.write(`\u001B[?25l${renderTitle()}\n ${cyan}▸ Installing dependencies with Bun...${reset}\u001B[1A\r`);
430
+ const timer = setInterval(() => {
431
+ stdout.write(`\u001B[2K${renderTitle()}\r`);
432
+ }, 120);
433
+ const finish = (title, detail) => {
434
+ clearInterval(timer);
435
+ stdout.write(`\u001B[2K\r\u001B[1B\r\u001B[2K\u001B[1A\r${title}\n${detail}\n\u001B[?25h`);
436
+ };
437
+ return {
438
+ fail() {
439
+ finish(`${cyan}▲${reset} Project initialization failed.`, "");
440
+ },
441
+ succeed() {
442
+ finish(`${green}✓ Project initialized!${reset}`, ` ${dim}▪ Dependencies installed${reset}\n`);
443
+ }
444
+ };
445
+ }
446
+ function printResult(result, log, interactive) {
447
+ const message = [
448
+ "🛠️ Next steps:",
449
+ ` cd ${formatProjectDirectory(result.projectDirectory)}`,
450
+ ...result.installed ? [] : [" bun install"],
451
+ " bun run dev",
452
+ "",
453
+ "🤖 Android:",
454
+ " bun run run:android",
455
+ " bun run create:aab"
456
+ ].join("\n");
457
+ const farewell = `Good luck out there, ${result.projectName}! 🎉`;
458
+ if (interactive) {
459
+ prompts.note(message, "Result");
460
+ prompts.outro(farewell);
461
+ return;
462
+ }
463
+ log(`${message}\n\n${farewell}`);
464
+ }
465
+ function formatProjectDirectory(projectDirectory) {
466
+ const relativeDirectory = path.relative(process.cwd(), projectDirectory);
467
+ const cwdPath = relativeDirectory.length === 0 ? "." : relativeDirectory.startsWith("..") || path.isAbsolute(relativeDirectory) ? relativeDirectory : `.${path.sep}${relativeDirectory}`;
468
+ const homeRelative = path.relative(homedir(), projectDirectory);
469
+ const homePath = homeRelative.length === 0 ? "~" : homeRelative.startsWith("..") || path.isAbsolute(homeRelative) ? void 0 : `~/${homeRelative.split(path.sep).join("/")}`;
470
+ const shortestPath = homePath !== void 0 && homePath.length < cwdPath.length ? homePath : cwdPath;
471
+ return /\s/u.test(shortestPath) ? JSON.stringify(shortestPath) : shortestPath;
387
472
  }
388
473
  async function readCreatorVersion() {
389
474
  const packageJson = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
@@ -23,10 +23,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  let _clack_prompts = require("@clack/prompts");
24
24
  _clack_prompts = __toESM(_clack_prompts, 1);
25
25
  let node_fs_promises = require("node:fs/promises");
26
- let node_process = require("node:process");
27
- let node_child_process = require("node:child_process");
26
+ let node_os = require("node:os");
28
27
  let node_path = require("node:path");
29
28
  node_path = __toESM(node_path, 1);
29
+ let node_process = require("node:process");
30
+ let node_child_process = require("node:child_process");
30
31
  let node_url = require("node:url");
31
32
  let jilatax = require("jilatax");
32
33
  //#region src/generator.ts
@@ -63,7 +64,7 @@ async function createProject(options) {
63
64
  throw error;
64
65
  }
65
66
  const shouldInstall = options.install === true;
66
- if (shouldInstall) await (options.installer ?? installWithBun)(projectDirectory);
67
+ if (shouldInstall) await (options.installer ?? ((directory) => installWithBun(directory, options.silentInstall === true)))(projectDirectory);
67
68
  return {
68
69
  displayName,
69
70
  installed: shouldInstall,
@@ -218,12 +219,12 @@ async function assertTargetDoesNotExist(target) {
218
219
  function titleCase$1(value) {
219
220
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
220
221
  }
221
- function installWithBun(projectDirectory) {
222
+ function installWithBun(projectDirectory, silent) {
222
223
  return new Promise((resolveInstall, rejectInstall) => {
223
224
  const child = (0, node_child_process.spawn)("bun", ["install"], {
224
225
  cwd: projectDirectory,
225
226
  env: process.env,
226
- stdio: "inherit",
227
+ stdio: silent ? "ignore" : "inherit",
227
228
  windowsHide: true
228
229
  });
229
230
  child.once("error", rejectInstall);
@@ -252,13 +253,25 @@ async function runCreateCli(args = process.argv.slice(2), services = {}) {
252
253
  log(await readCreatorVersion());
253
254
  return 0;
254
255
  }
255
- const options = services.interactive ?? (node_process.stdin.isTTY && node_process.stdout.isTTY) ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
256
- printResult(await (services.create ?? createProject)({
257
- displayName: options.displayName,
258
- install: options.install,
259
- packageId: options.packageId,
260
- targetDirectory: options.targetDirectory
261
- }), log);
256
+ const interactive = services.interactive ?? (node_process.stdin.isTTY && node_process.stdout.isTTY);
257
+ const options = interactive ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
258
+ const generate = services.create ?? createProject;
259
+ const progress = interactive && options.install ? startInstallProgress() : void 0;
260
+ let result;
261
+ try {
262
+ result = await generate({
263
+ displayName: options.displayName,
264
+ install: options.install,
265
+ packageId: options.packageId,
266
+ ...progress === void 0 ? {} : { silentInstall: true },
267
+ targetDirectory: options.targetDirectory
268
+ });
269
+ } catch (error) {
270
+ progress?.fail();
271
+ throw error;
272
+ }
273
+ progress?.succeed();
274
+ printResult(result, log, interactive);
262
275
  return 0;
263
276
  } catch (error) {
264
277
  if (error instanceof PromptCancelledError) return 0;
@@ -316,7 +329,7 @@ function parseArgs(args) {
316
329
  };
317
330
  }
318
331
  async function promptForOptions(options) {
319
- _clack_prompts.intro("Jilatax · Android-first Lynx application");
332
+ printWelcome(await readCreatorVersion());
320
333
  const targetDirectory = options.targetDirectory ?? unwrapPrompt(await _clack_prompts.text({
321
334
  message: "Where should the project be created?",
322
335
  placeholder: "./my-jilatax-app",
@@ -329,17 +342,7 @@ async function promptForOptions(options) {
329
342
  }
330
343
  }));
331
344
  const projectName = normalizeProjectNameFromDirectory(targetDirectory);
332
- const displayName = options.displayName ?? unwrapPrompt(await _clack_prompts.text({
333
- initialValue: titleCase(projectName),
334
- message: "Application name",
335
- validate(value) {
336
- try {
337
- normalizeDisplayName(value ?? "");
338
- } catch (error) {
339
- return validationMessage(error);
340
- }
341
- }
342
- }));
345
+ const displayName = options.displayName ?? titleCase(projectName);
343
346
  const packageId = options.packageId ?? unwrapPrompt(await _clack_prompts.text({
344
347
  initialValue: defaultPackageId(projectName),
345
348
  message: "Android application ID",
@@ -352,7 +355,7 @@ async function promptForOptions(options) {
352
355
  }
353
356
  }));
354
357
  const install = options.install ?? unwrapPrompt(await _clack_prompts.confirm({
355
- initialValue: true,
358
+ initialValue: false,
356
359
  message: "Install dependencies with Bun?"
357
360
  }));
358
361
  return {
@@ -398,16 +401,98 @@ function readInlineValue(argument, option) {
398
401
  function titleCase(value) {
399
402
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
400
403
  }
401
- function printResult(result, log) {
402
- const installStep = result.installed ? "" : " bun install\n";
403
- log(`Created ${result.displayName} in ${result.projectDirectory}.
404
-
405
- Next steps:
406
- cd ${JSON.stringify(result.projectDirectory)}
407
- ${installStep} bun run run:android
408
-
409
- Release bundle:
410
- bun run create:aab`);
404
+ function printWelcome(version) {
405
+ const reset = "\x1B[0m";
406
+ const cyan = "\x1B[36m";
407
+ const brightCyan = "\x1B[96m";
408
+ const green = "\x1B[32m";
409
+ const bold = "\x1B[1m";
410
+ const dim = "\x1B[2m";
411
+ const mascot = [`${cyan}╲╲_${brightCyan}╱╱${reset}`, `${cyan}(${green}●${cyan}▽${green}●${cyan})${reset}`];
412
+ const welcome = [`${bold}${brightCyan}JILATAX${reset} ${dim}v${version}${reset}`, `${dim}Welcome.${reset} Build your next Android-first app.`];
413
+ console.log(`${mascot.map((line, index) => `${line} ${welcome[index]}`).join("\n")}\n`);
414
+ }
415
+ function startInstallProgress() {
416
+ const reset = "\x1B[0m";
417
+ const cyan = "\x1B[36m";
418
+ const dim = "\x1B[2m";
419
+ const green = "\x1B[32m";
420
+ const frames = [
421
+ [
422
+ 45,
423
+ 105,
424
+ 44,
425
+ 46
426
+ ],
427
+ [
428
+ 105,
429
+ 44,
430
+ 46,
431
+ 45
432
+ ],
433
+ [
434
+ 44,
435
+ 46,
436
+ 45,
437
+ 105
438
+ ],
439
+ [
440
+ 46,
441
+ 45,
442
+ 105,
443
+ 44
444
+ ]
445
+ ];
446
+ let frameIndex = 0;
447
+ const renderBar = () => {
448
+ const colors = frames[frameIndex % frames.length] ?? frames[0];
449
+ frameIndex += 1;
450
+ return `${colors.map((color) => `\u001B[${color}m `).join("")}${reset}`;
451
+ };
452
+ const renderTitle = () => `${renderBar()} Project initializing...`;
453
+ node_process.stdout.write(`\u001B[?25l${renderTitle()}\n ${cyan}▸ Installing dependencies with Bun...${reset}\u001B[1A\r`);
454
+ const timer = setInterval(() => {
455
+ node_process.stdout.write(`\u001B[2K${renderTitle()}\r`);
456
+ }, 120);
457
+ const finish = (title, detail) => {
458
+ clearInterval(timer);
459
+ node_process.stdout.write(`\u001B[2K\r\u001B[1B\r\u001B[2K\u001B[1A\r${title}\n${detail}\n\u001B[?25h`);
460
+ };
461
+ return {
462
+ fail() {
463
+ finish(`${cyan}▲${reset} Project initialization failed.`, "");
464
+ },
465
+ succeed() {
466
+ finish(`${green}✓ Project initialized!${reset}`, ` ${dim}▪ Dependencies installed${reset}\n`);
467
+ }
468
+ };
469
+ }
470
+ function printResult(result, log, interactive) {
471
+ const message = [
472
+ "🛠️ Next steps:",
473
+ ` cd ${formatProjectDirectory(result.projectDirectory)}`,
474
+ ...result.installed ? [] : [" bun install"],
475
+ " bun run dev",
476
+ "",
477
+ "🤖 Android:",
478
+ " bun run run:android",
479
+ " bun run create:aab"
480
+ ].join("\n");
481
+ const farewell = `Good luck out there, ${result.projectName}! 🎉`;
482
+ if (interactive) {
483
+ _clack_prompts.note(message, "Result");
484
+ _clack_prompts.outro(farewell);
485
+ return;
486
+ }
487
+ log(`${message}\n\n${farewell}`);
488
+ }
489
+ function formatProjectDirectory(projectDirectory) {
490
+ const relativeDirectory = node_path.default.relative(process.cwd(), projectDirectory);
491
+ const cwdPath = relativeDirectory.length === 0 ? "." : relativeDirectory.startsWith("..") || node_path.default.isAbsolute(relativeDirectory) ? relativeDirectory : `.${node_path.default.sep}${relativeDirectory}`;
492
+ const homeRelative = node_path.default.relative((0, node_os.homedir)(), projectDirectory);
493
+ const homePath = homeRelative.length === 0 ? "~" : homeRelative.startsWith("..") || node_path.default.isAbsolute(homeRelative) ? void 0 : `~/${homeRelative.split(node_path.default.sep).join("/")}`;
494
+ const shortestPath = homePath !== void 0 && homePath.length < cwdPath.length ? homePath : cwdPath;
495
+ return /\s/u.test(shortestPath) ? JSON.stringify(shortestPath) : shortestPath;
411
496
  }
412
497
  async function readCreatorVersion() {
413
498
  const packageJson = JSON.parse(await (0, node_fs_promises.readFile)(new URL("../package.json", require("url").pathToFileURL(__filename).href), "utf8"));
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_cli = require("./cli-DD2gvmMZ.cjs");
2
+ const require_cli = require("./cli-DE3ovkQR.cjs");
3
3
  exports.createHelpText = require_cli.createHelpText;
4
4
  exports.createProject = require_cli.createProject;
5
5
  exports.defaultPackageId = require_cli.defaultPackageId;
package/dist/index.d.cts CHANGED
@@ -4,6 +4,7 @@ interface CreateProjectOptions {
4
4
  readonly install?: boolean;
5
5
  readonly installer?: ProjectInstaller;
6
6
  readonly packageId?: string;
7
+ readonly silentInstall?: boolean;
7
8
  readonly targetDirectory: string;
8
9
  }
9
10
  interface CreateProjectResult {
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ interface CreateProjectOptions {
4
4
  readonly install?: boolean;
5
5
  readonly installer?: ProjectInstaller;
6
6
  readonly packageId?: string;
7
+ readonly silentInstall?: boolean;
7
8
  readonly targetDirectory: string;
8
9
  }
9
10
  interface CreateProjectResult {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as normalizeDisplayName, i as defaultPackageId, n as runCreateCli, o as normalizeProjectName, r as createProject, s as validatePackageId, t as createHelpText } from "./cli-DLBJ0XnY.js";
1
+ import { a as normalizeDisplayName, i as defaultPackageId, n as runCreateCli, o as normalizeProjectName, r as createProject, s as validatePackageId, t as createHelpText } from "./cli-Bd5vJvDf.js";
2
2
  export { createHelpText, createProject, defaultPackageId, normalizeDisplayName, normalizeProjectName, runCreateCli, validatePackageId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jilatax",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "packageManager": "bun@1.3.4",
5
5
  "description": "Create an Android-first Jilatax application for Lynx and Rspeedy.",
6
6
  "type": "module",