create-jilatax 0.0.3 → 0.0.5

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 (43) hide show
  1. package/README.md +42 -23
  2. package/THIRD_PARTY_NOTICES.md +7 -0
  3. package/dist/bin.cjs +6 -0
  4. package/dist/bin.d.cts +1 -0
  5. package/dist/bin.d.ts +1 -0
  6. package/dist/bin.js +8 -0
  7. package/dist/cli-B8DIbCrH.js +387 -0
  8. package/dist/cli-DMT97_QW.cjs +452 -0
  9. package/dist/index.cjs +8 -6
  10. package/dist/index.d.cts +32 -3
  11. package/dist/index.d.ts +32 -3
  12. package/dist/index.js +2 -6
  13. package/package.json +13 -5
  14. package/template/README.md.tmpl +34 -0
  15. package/template/android/app/build.gradle.kts +112 -0
  16. package/template/android/app/proguard-rules.pro +1 -0
  17. package/template/android/app/src/debug/AndroidManifest.xml +8 -0
  18. package/template/android/app/src/main/AndroidManifest.xml +30 -0
  19. package/template/android/app/src/main/res/drawable/jilatax_mark_foreground.xml +11 -0
  20. package/template/android/app/src/main/res/drawable/jilatax_splash.xml +9 -0
  21. package/template/android/app/src/main/res/mipmap-anydpi/jilatax_launcher.xml +12 -0
  22. package/template/android/app/src/main/res/mipmap-anydpi/jilatax_launcher_round.xml +12 -0
  23. package/template/android/app/src/main/res/mipmap-anydpi-v26/jilatax_launcher.xml +5 -0
  24. package/template/android/app/src/main/res/mipmap-anydpi-v26/jilatax_launcher_round.xml +5 -0
  25. package/template/android/app/src/main/res/values/styles.xml +16 -0
  26. package/template/android/app/src/main/res/values-v31/styles.xml +8 -0
  27. package/template/android/build.gradle.kts +5 -0
  28. package/template/android/gradle/wrapper/gradle-wrapper.jar.base64 +1112 -0
  29. package/template/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  30. package/template/android/gradle.properties +6 -0
  31. package/template/android/gradlew +248 -0
  32. package/template/android/gradlew.bat +92 -0
  33. package/template/android/keystore.properties.example +5 -0
  34. package/template/android/settings.gradle.kts.tmpl +29 -0
  35. package/template/gitignore +22 -0
  36. package/template/lynx.config.ts +25 -0
  37. package/template/src/App.css +95 -0
  38. package/template/src/App.tsx.tmpl +23 -0
  39. package/template/src/index.tsx +9 -0
  40. package/template/src/rspeedy-env.d.ts +1 -0
  41. package/template/src/tsconfig.json +13 -0
  42. package/template/tsconfig.json +15 -0
  43. package/template/tsconfig.node.json +12 -0
@@ -0,0 +1,452 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ let _clack_prompts = require("@clack/prompts");
24
+ _clack_prompts = __toESM(_clack_prompts, 1);
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");
28
+ let node_path = require("node:path");
29
+ node_path = __toESM(node_path, 1);
30
+ let node_url = require("node:url");
31
+ let jilatax = require("jilatax");
32
+ //#region src/generator.ts
33
+ const JILATAX_CLI_VERSION = "^0.0.8";
34
+ const JILATAX_VERSION = "^0.0.5";
35
+ const LYNX_QRCODE_PLUGIN_VERSION = "^0.4.4";
36
+ const LYNX_REACT_VERSION = "^0.116.2";
37
+ const LYNX_TYPES_VERSION = "^3.7.0";
38
+ const REACT_PLUGIN_VERSION = "^0.12.7";
39
+ const RSPEEDY_VERSION = "^0.13.3";
40
+ const TEXT_TEMPLATE_FILES = /* @__PURE__ */ new Set([
41
+ "README.md.tmpl",
42
+ "android/settings.gradle.kts.tmpl",
43
+ "src/App.tsx.tmpl"
44
+ ]);
45
+ async function createProject(options) {
46
+ const projectDirectory = node_path.default.resolve(options.targetDirectory);
47
+ const projectName = normalizeProjectName(node_path.default.basename(projectDirectory));
48
+ const displayName = normalizeDisplayName(options.displayName ?? titleCase$1(projectName));
49
+ const packageId = validatePackageId(options.packageId ?? defaultPackageId(projectName));
50
+ const config = createInitialConfig(displayName, projectName, packageId);
51
+ await assertTargetDoesNotExist(projectDirectory);
52
+ const parentDirectory = node_path.default.dirname(projectDirectory);
53
+ await (0, node_fs_promises.mkdir)(parentDirectory, { recursive: true });
54
+ const stagingDirectory = await (0, node_fs_promises.mkdtemp)(node_path.default.join(parentDirectory, `.${projectName}-`));
55
+ try {
56
+ await renderTemplate(stagingDirectory, {
57
+ displayName,
58
+ projectName
59
+ });
60
+ await writeGeneratedMetadata(stagingDirectory, config, projectName);
61
+ await (0, node_fs_promises.rename)(stagingDirectory, projectDirectory);
62
+ } catch (error) {
63
+ await (0, node_fs_promises.rm)(stagingDirectory, {
64
+ force: true,
65
+ recursive: true
66
+ });
67
+ throw error;
68
+ }
69
+ const shouldInstall = options.install === true;
70
+ if (shouldInstall) await (options.installer ?? installWithBun)(projectDirectory);
71
+ return {
72
+ displayName,
73
+ installed: shouldInstall,
74
+ packageId,
75
+ projectDirectory,
76
+ projectName
77
+ };
78
+ }
79
+ function normalizeProjectName(value) {
80
+ const projectName = value.trim().toLowerCase();
81
+ if (!/^[a-z0-9][a-z0-9._-]*$/u.test(projectName) || projectName.length > 214) throw new Error("Project directory name must start with a letter or number and contain only lowercase letters, numbers, dots, hyphens, or underscores.");
82
+ return projectName;
83
+ }
84
+ function normalizeDisplayName(value) {
85
+ const displayName = value.trim().replace(/\s+/gu, " ");
86
+ if (displayName.length === 0 || displayName.length > 80) throw new Error("Application name must contain between 1 and 80 characters.");
87
+ return displayName;
88
+ }
89
+ function defaultPackageId(projectName) {
90
+ return `com.example.${projectName.replace(/[^a-z0-9_]+/gu, "_").replace(/^[^a-z]+/u, "").replace(/_+$/gu, "") || "app"}`;
91
+ }
92
+ function validatePackageId(value) {
93
+ const packageId = value.trim();
94
+ (0, jilatax.parseAppConfig)({ jilatax: {
95
+ android: { package: packageId },
96
+ name: "Package validation"
97
+ } });
98
+ return packageId;
99
+ }
100
+ async function renderTemplate(targetRoot, values) {
101
+ await copyTemplateDirectory((0, node_url.fileURLToPath)(new URL("../template", require("url").pathToFileURL(__filename).href)), targetRoot, "", values);
102
+ }
103
+ async function copyTemplateDirectory(templateRoot, targetRoot, relativeDirectory, values) {
104
+ const entries = await (0, node_fs_promises.readdir)(node_path.default.join(templateRoot, relativeDirectory), { withFileTypes: true });
105
+ for (const entry of entries) {
106
+ const relativeSource = node_path.default.join(relativeDirectory, entry.name);
107
+ const normalizedSource = relativeSource.split(node_path.default.sep).join("/");
108
+ const sourcePath = node_path.default.join(templateRoot, relativeSource);
109
+ if (entry.isSymbolicLink() || !entry.isDirectory() && !entry.isFile()) throw new Error(`Unsupported template entry: ${normalizedSource}`);
110
+ if (entry.isDirectory()) {
111
+ await copyTemplateDirectory(templateRoot, targetRoot, relativeSource, values);
112
+ continue;
113
+ }
114
+ const outputRelative = templateOutputPath(normalizedSource);
115
+ const outputPath = node_path.default.join(targetRoot, ...outputRelative.split("/"));
116
+ await (0, node_fs_promises.mkdir)(node_path.default.dirname(outputPath), { recursive: true });
117
+ if (normalizedSource.endsWith("gradle-wrapper.jar.base64")) {
118
+ const encoded = (await (0, node_fs_promises.readFile)(sourcePath, "utf8")).replace(/\s+/gu, "");
119
+ await (0, node_fs_promises.writeFile)(outputPath, Buffer.from(encoded, "base64"));
120
+ continue;
121
+ }
122
+ if (TEXT_TEMPLATE_FILES.has(normalizedSource)) {
123
+ await (0, node_fs_promises.writeFile)(outputPath, renderTextTemplate(await (0, node_fs_promises.readFile)(sourcePath, "utf8"), values), "utf8");
124
+ continue;
125
+ }
126
+ if (normalizedSource.endsWith(".tmpl")) throw new Error(`Unregistered text template: ${normalizedSource}`);
127
+ await (0, node_fs_promises.copyFile)(sourcePath, outputPath);
128
+ }
129
+ }
130
+ function templateOutputPath(relativeSource) {
131
+ if (relativeSource === "gitignore") return ".gitignore";
132
+ if (relativeSource.endsWith("gradle-wrapper.jar.base64")) return relativeSource.slice(0, -7);
133
+ return relativeSource.endsWith(".tmpl") ? relativeSource.slice(0, -5) : relativeSource;
134
+ }
135
+ function renderTextTemplate(source, values) {
136
+ const replacements = /* @__PURE__ */ new Map([
137
+ ["{{displayNameJson}}", JSON.stringify(values.displayName)],
138
+ ["{{projectName}}", values.projectName],
139
+ ["{{projectNameJson}}", JSON.stringify(values.projectName)]
140
+ ]);
141
+ let rendered = source;
142
+ for (const [token, replacement] of replacements) rendered = rendered.replaceAll(token, replacement);
143
+ const unresolved = rendered.match(/\{\{[A-Za-z][A-Za-z0-9]*\}\}/u);
144
+ if (unresolved !== null) throw new Error(`Unresolved template token: ${unresolved[0]}`);
145
+ return rendered;
146
+ }
147
+ async function writeGeneratedMetadata(projectRoot, config, projectName) {
148
+ const packageJson = {
149
+ name: projectName,
150
+ version: config.jilatax.version,
151
+ private: true,
152
+ type: "module",
153
+ packageManager: "bun@1.3.4",
154
+ engines: { node: ">=22.18.0" },
155
+ scripts: {
156
+ dev: "rspeedy dev",
157
+ build: "rspeedy build",
158
+ typecheck: "tsc -b",
159
+ "run:android": "jilatax run:android",
160
+ "create:aab": "jilatax create:aab"
161
+ },
162
+ dependencies: {
163
+ "@lynx-js/react": LYNX_REACT_VERSION,
164
+ jilatax: JILATAX_VERSION
165
+ },
166
+ devDependencies: {
167
+ "@jilatax/cli": JILATAX_CLI_VERSION,
168
+ "@lynx-js/qrcode-rsbuild-plugin": LYNX_QRCODE_PLUGIN_VERSION,
169
+ "@lynx-js/react-rsbuild-plugin": REACT_PLUGIN_VERSION,
170
+ "@lynx-js/rspeedy": RSPEEDY_VERSION,
171
+ "@lynx-js/types": LYNX_TYPES_VERSION,
172
+ "@types/node": "^22.20.1",
173
+ "@types/react": "^18.3.20",
174
+ typescript: "~5.9.3"
175
+ }
176
+ };
177
+ await (0, node_fs_promises.writeFile)(node_path.default.join(projectRoot, "package.json"), `${JSON.stringify(packageJson, null, 2)}\n`, "utf8");
178
+ await (0, node_fs_promises.writeFile)(node_path.default.join(projectRoot, "app.json"), `${JSON.stringify(config, null, 2)}\n`, "utf8");
179
+ await (0, node_fs_promises.writeFile)(node_path.default.join(projectRoot, "android", "jilatax.properties"), (0, jilatax.serializeAndroidProjectConfig)(config), "utf8");
180
+ if (process.platform !== "win32") await (0, node_fs_promises.chmod)(node_path.default.join(projectRoot, "android", "gradlew"), 493);
181
+ }
182
+ function createInitialConfig(displayName, projectName, packageId) {
183
+ const slug = projectName.replace(/[._-]+/gu, "-").replace(/^-|-$/gu, "");
184
+ const schemeBase = projectName.replace(/[^a-z0-9+.-]+/gu, "-").replace(/^[^a-z]+/u, "");
185
+ return (0, jilatax.parseAppConfig)({
186
+ $schema: "./node_modules/jilatax/schema/app.schema.json",
187
+ jilatax: {
188
+ android: {
189
+ package: packageId,
190
+ predictiveBackGestureEnabled: false,
191
+ versionCode: 1
192
+ },
193
+ name: displayName,
194
+ orientation: "portrait",
195
+ scheme: schemeBase || "jilatax-app",
196
+ slug,
197
+ splash: { backgroundColor: "#0F172A" },
198
+ userInterfaceStyle: "automatic",
199
+ version: "1.0.0"
200
+ }
201
+ });
202
+ }
203
+ async function assertTargetDoesNotExist(target) {
204
+ try {
205
+ await (0, node_fs_promises.lstat)(target);
206
+ } catch (error) {
207
+ if (error.code === "ENOENT") return;
208
+ throw error;
209
+ }
210
+ throw new Error(`Target directory already exists: ${target}`);
211
+ }
212
+ function titleCase$1(value) {
213
+ return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
214
+ }
215
+ function installWithBun(projectDirectory) {
216
+ return new Promise((resolveInstall, rejectInstall) => {
217
+ const child = (0, node_child_process.spawn)("bun", ["install"], {
218
+ cwd: projectDirectory,
219
+ env: process.env,
220
+ stdio: "inherit",
221
+ windowsHide: true
222
+ });
223
+ child.once("error", rejectInstall);
224
+ child.once("close", (code) => {
225
+ if (code === 0) {
226
+ resolveInstall();
227
+ return;
228
+ }
229
+ rejectInstall(/* @__PURE__ */ new Error(`bun install failed with exit code ${code ?? 1}.`));
230
+ });
231
+ });
232
+ }
233
+ //#endregion
234
+ //#region src/cli.ts
235
+ var PromptCancelledError = class extends Error {};
236
+ async function runCreateCli(args = process.argv.slice(2), services = {}) {
237
+ const log = services.log ?? console.log;
238
+ const warn = services.warn ?? console.error;
239
+ try {
240
+ const parsed = parseArgs(args);
241
+ if (parsed.showHelp) {
242
+ log(createHelpText());
243
+ return 0;
244
+ }
245
+ if (parsed.showVersion) {
246
+ log(await readCreatorVersion());
247
+ return 0;
248
+ }
249
+ const options = services.interactive ?? (node_process.stdin.isTTY && node_process.stdout.isTTY) ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
250
+ printResult(await (services.create ?? createProject)({
251
+ displayName: options.displayName,
252
+ install: options.install,
253
+ packageId: options.packageId,
254
+ targetDirectory: options.targetDirectory
255
+ }), log);
256
+ return 0;
257
+ } catch (error) {
258
+ if (error instanceof PromptCancelledError) return 0;
259
+ warn(error instanceof Error ? error.message : String(error));
260
+ return 1;
261
+ }
262
+ }
263
+ function createHelpText() {
264
+ return `Create an Android-first Jilatax application.
265
+
266
+ Usage:
267
+ create-jilatax [directory] [options]
268
+
269
+ Options:
270
+ --name <display-name> Human-readable application name
271
+ --package-id <id> Android application ID
272
+ --install Install dependencies with Bun
273
+ --skip-install Generate without installing dependencies
274
+ -h, --help Show this help
275
+ -V, --version Show the installed creator version`;
276
+ }
277
+ function parseArgs(args) {
278
+ let displayName;
279
+ let install;
280
+ let packageId;
281
+ let showHelp = false;
282
+ let showVersion = false;
283
+ let targetDirectory;
284
+ for (let index = 0; index < args.length; index += 1) {
285
+ const argument = args[index];
286
+ if (argument === void 0) continue;
287
+ if (argument === "--install") install = true;
288
+ else if (argument === "--skip-install" || argument === "--no-install") install = false;
289
+ else if (argument === "--name") {
290
+ displayName = readOptionValue(args, index, argument);
291
+ index += 1;
292
+ } else if (argument.startsWith("--name=")) displayName = readInlineValue(argument, "--name");
293
+ else if (argument === "--package-id") {
294
+ packageId = readOptionValue(args, index, argument);
295
+ index += 1;
296
+ } else if (argument.startsWith("--package-id=")) packageId = readInlineValue(argument, "--package-id");
297
+ else if (argument === "--help" || argument === "-h") showHelp = true;
298
+ else if (argument === "--version" || argument === "-V") showVersion = true;
299
+ else if (argument.startsWith("-")) throw new Error(`Unknown option: ${argument}`);
300
+ else if (targetDirectory === void 0) targetDirectory = argument;
301
+ else throw new Error(`Unexpected argument: ${argument}`);
302
+ }
303
+ return {
304
+ ...displayName === void 0 ? {} : { displayName },
305
+ ...install === void 0 ? {} : { install },
306
+ ...packageId === void 0 ? {} : { packageId },
307
+ showHelp,
308
+ showVersion,
309
+ ...targetDirectory === void 0 ? {} : { targetDirectory }
310
+ };
311
+ }
312
+ async function promptForOptions(options) {
313
+ _clack_prompts.intro("Jilatax · Android-first Lynx application");
314
+ const targetDirectory = options.targetDirectory ?? unwrapPrompt(await _clack_prompts.text({
315
+ message: "Where should the project be created?",
316
+ placeholder: "./my-jilatax-app",
317
+ validate(value) {
318
+ try {
319
+ normalizeProjectNameFromDirectory(value ?? "");
320
+ } catch (error) {
321
+ return validationMessage(error);
322
+ }
323
+ }
324
+ }));
325
+ const projectName = normalizeProjectNameFromDirectory(targetDirectory);
326
+ const displayName = options.displayName ?? unwrapPrompt(await _clack_prompts.text({
327
+ initialValue: titleCase(projectName),
328
+ message: "Application name",
329
+ validate(value) {
330
+ try {
331
+ normalizeDisplayName(value ?? "");
332
+ } catch (error) {
333
+ return validationMessage(error);
334
+ }
335
+ }
336
+ }));
337
+ const packageId = options.packageId ?? unwrapPrompt(await _clack_prompts.text({
338
+ initialValue: defaultPackageId(projectName),
339
+ message: "Android application ID",
340
+ validate(value) {
341
+ try {
342
+ validatePackageId(value ?? "");
343
+ } catch (error) {
344
+ return validationMessage(error);
345
+ }
346
+ }
347
+ }));
348
+ const install = options.install ?? unwrapPrompt(await _clack_prompts.confirm({
349
+ initialValue: true,
350
+ message: "Install dependencies with Bun?"
351
+ }));
352
+ return {
353
+ displayName: normalizeDisplayName(displayName),
354
+ install,
355
+ packageId: validatePackageId(packageId),
356
+ targetDirectory
357
+ };
358
+ }
359
+ function nonInteractiveOptions(options) {
360
+ if (options.targetDirectory === void 0) throw new Error("Project directory is required in a non-interactive terminal.");
361
+ const projectName = normalizeProjectNameFromDirectory(options.targetDirectory);
362
+ return {
363
+ displayName: normalizeDisplayName(options.displayName ?? titleCase(projectName)),
364
+ install: options.install ?? false,
365
+ packageId: validatePackageId(options.packageId ?? defaultPackageId(projectName)),
366
+ targetDirectory: options.targetDirectory
367
+ };
368
+ }
369
+ function normalizeProjectNameFromDirectory(directory) {
370
+ return normalizeProjectName(directory.trim().replace(/[\\/]+$/gu, "").split(/[\\/]/u).at(-1) ?? "");
371
+ }
372
+ function unwrapPrompt(value) {
373
+ if (_clack_prompts.isCancel(value)) {
374
+ _clack_prompts.cancel("Project creation cancelled.");
375
+ throw new PromptCancelledError();
376
+ }
377
+ return value;
378
+ }
379
+ function validationMessage(error) {
380
+ return error instanceof Error ? error.message : String(error);
381
+ }
382
+ function readOptionValue(args, index, option) {
383
+ const value = args[index + 1];
384
+ if (value === void 0 || value.startsWith("-") || value.trim().length === 0) throw new Error(`${option} requires a value.`);
385
+ return value.trim();
386
+ }
387
+ function readInlineValue(argument, option) {
388
+ const value = argument.slice(`${option}=`.length).trim();
389
+ if (value.length === 0) throw new Error(`${option} requires a value.`);
390
+ return value;
391
+ }
392
+ function titleCase(value) {
393
+ return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
394
+ }
395
+ function printResult(result, log) {
396
+ const installStep = result.installed ? "" : " bun install\n";
397
+ log(`Created ${result.displayName} in ${result.projectDirectory}.
398
+
399
+ Next steps:
400
+ cd ${JSON.stringify(result.projectDirectory)}
401
+ ${installStep} bun run run:android
402
+
403
+ Release bundle:
404
+ bun run create:aab`);
405
+ }
406
+ async function readCreatorVersion() {
407
+ const packageJson = JSON.parse(await (0, node_fs_promises.readFile)(new URL("../package.json", require("url").pathToFileURL(__filename).href), "utf8"));
408
+ return typeof packageJson.version === "string" ? packageJson.version : "unknown";
409
+ }
410
+ //#endregion
411
+ Object.defineProperty(exports, "createHelpText", {
412
+ enumerable: true,
413
+ get: function() {
414
+ return createHelpText;
415
+ }
416
+ });
417
+ Object.defineProperty(exports, "createProject", {
418
+ enumerable: true,
419
+ get: function() {
420
+ return createProject;
421
+ }
422
+ });
423
+ Object.defineProperty(exports, "defaultPackageId", {
424
+ enumerable: true,
425
+ get: function() {
426
+ return defaultPackageId;
427
+ }
428
+ });
429
+ Object.defineProperty(exports, "normalizeDisplayName", {
430
+ enumerable: true,
431
+ get: function() {
432
+ return normalizeDisplayName;
433
+ }
434
+ });
435
+ Object.defineProperty(exports, "normalizeProjectName", {
436
+ enumerable: true,
437
+ get: function() {
438
+ return normalizeProjectName;
439
+ }
440
+ });
441
+ Object.defineProperty(exports, "runCreateCli", {
442
+ enumerable: true,
443
+ get: function() {
444
+ return runCreateCli;
445
+ }
446
+ });
447
+ Object.defineProperty(exports, "validatePackageId", {
448
+ enumerable: true,
449
+ get: function() {
450
+ return validatePackageId;
451
+ }
452
+ });
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region src/index.ts
3
- function hello(name) {
4
- return `Hello, ${name}!`;
5
- }
6
- //#endregion
7
- exports.hello = hello;
2
+ const require_cli = require("./cli-DMT97_QW.cjs");
3
+ exports.createHelpText = require_cli.createHelpText;
4
+ exports.createProject = require_cli.createProject;
5
+ exports.defaultPackageId = require_cli.defaultPackageId;
6
+ exports.normalizeDisplayName = require_cli.normalizeDisplayName;
7
+ exports.normalizeProjectName = require_cli.normalizeProjectName;
8
+ exports.runCreateCli = require_cli.runCreateCli;
9
+ exports.validatePackageId = require_cli.validatePackageId;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,33 @@
1
- //#region src/index.d.ts
2
- declare function hello(name: string): string;
1
+ //#region src/generator.d.ts
2
+ interface CreateProjectOptions {
3
+ readonly displayName?: string;
4
+ readonly install?: boolean;
5
+ readonly installer?: ProjectInstaller;
6
+ readonly packageId?: string;
7
+ readonly targetDirectory: string;
8
+ }
9
+ interface CreateProjectResult {
10
+ readonly displayName: string;
11
+ readonly installed: boolean;
12
+ readonly packageId: string;
13
+ readonly projectDirectory: string;
14
+ readonly projectName: string;
15
+ }
16
+ type ProjectInstaller = (projectDirectory: string) => Promise<void>;
17
+ declare function createProject(options: CreateProjectOptions): Promise<CreateProjectResult>;
18
+ declare function normalizeProjectName(value: string): string;
19
+ declare function normalizeDisplayName(value: string): string;
20
+ declare function defaultPackageId(projectName: string): string;
21
+ declare function validatePackageId(value: string): string;
3
22
  //#endregion
4
- export { hello };
23
+ //#region src/cli.d.ts
24
+ interface CreateCliServices {
25
+ readonly create?: typeof createProject;
26
+ readonly interactive?: boolean;
27
+ readonly log?: (message: string) => void;
28
+ readonly warn?: (message: string) => void;
29
+ }
30
+ declare function runCreateCli(args?: readonly string[], services?: CreateCliServices): Promise<number>;
31
+ declare function createHelpText(): string;
32
+ //#endregion
33
+ export { type CreateCliServices, type CreateProjectOptions, type CreateProjectResult, type ProjectInstaller, createHelpText, createProject, defaultPackageId, normalizeDisplayName, normalizeProjectName, runCreateCli, validatePackageId };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,33 @@
1
- //#region src/index.d.ts
2
- declare function hello(name: string): string;
1
+ //#region src/generator.d.ts
2
+ interface CreateProjectOptions {
3
+ readonly displayName?: string;
4
+ readonly install?: boolean;
5
+ readonly installer?: ProjectInstaller;
6
+ readonly packageId?: string;
7
+ readonly targetDirectory: string;
8
+ }
9
+ interface CreateProjectResult {
10
+ readonly displayName: string;
11
+ readonly installed: boolean;
12
+ readonly packageId: string;
13
+ readonly projectDirectory: string;
14
+ readonly projectName: string;
15
+ }
16
+ type ProjectInstaller = (projectDirectory: string) => Promise<void>;
17
+ declare function createProject(options: CreateProjectOptions): Promise<CreateProjectResult>;
18
+ declare function normalizeProjectName(value: string): string;
19
+ declare function normalizeDisplayName(value: string): string;
20
+ declare function defaultPackageId(projectName: string): string;
21
+ declare function validatePackageId(value: string): string;
3
22
  //#endregion
4
- export { hello };
23
+ //#region src/cli.d.ts
24
+ interface CreateCliServices {
25
+ readonly create?: typeof createProject;
26
+ readonly interactive?: boolean;
27
+ readonly log?: (message: string) => void;
28
+ readonly warn?: (message: string) => void;
29
+ }
30
+ declare function runCreateCli(args?: readonly string[], services?: CreateCliServices): Promise<number>;
31
+ declare function createHelpText(): string;
32
+ //#endregion
33
+ export { type CreateCliServices, type CreateProjectOptions, type CreateProjectResult, type ProjectInstaller, createHelpText, createProject, defaultPackageId, normalizeDisplayName, normalizeProjectName, runCreateCli, validatePackageId };
package/dist/index.js CHANGED
@@ -1,6 +1,2 @@
1
- //#region src/index.ts
2
- function hello(name) {
3
- return `Hello, ${name}!`;
4
- }
5
- //#endregion
6
- export { hello };
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-B8DIbCrH.js";
2
+ export { createHelpText, createProject, defaultPackageId, normalizeDisplayName, normalizeProjectName, runCreateCli, validatePackageId };
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "create-jilatax",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "packageManager": "bun@1.3.4",
5
- "description": "A minimal TypeScript library package with ESM, CommonJS, and declaration outputs.",
5
+ "description": "Create an Android-first Jilatax application for Lynx and Rspeedy.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",
8
8
  "module": "./dist/index.js",
9
9
  "types": "./dist/index.d.ts",
10
+ "bin": {
11
+ "create-jilatax": "./dist/bin.js"
12
+ },
10
13
  "exports": {
11
14
  ".": {
12
15
  "import": {
@@ -19,10 +22,10 @@
19
22
  }
20
23
  }
21
24
  },
22
- "files": ["dist"],
23
- "sideEffects": false,
25
+ "files": ["dist", "template", "THIRD_PARTY_NOTICES.md"],
26
+ "sideEffects": ["./dist/bin.js"],
24
27
 
25
- "keywords": ["typescript", "esm", "commonjs"],
28
+ "keywords": ["android", "creator", "jilatax", "lynx", "rspeedy"],
26
29
  "author": "Gohit X (bastndev)",
27
30
  "license": "MIT",
28
31
  "homepage": "https://jilatax.dev/jilatax",
@@ -40,6 +43,11 @@
40
43
  "node": ">=22.18.0"
41
44
  },
42
45
 
46
+ "dependencies": {
47
+ "@clack/prompts": "^1.7.0",
48
+ "jilatax": "^0.0.5"
49
+ },
50
+
43
51
  "devDependencies": {
44
52
  "@arethetypeswrong/core": "^0.18.5",
45
53
  "@types/node": "^22.20.1",
@@ -0,0 +1,34 @@
1
+ # {{projectName}}
2
+
3
+ Android-first Lynx application created with Jilatax.
4
+
5
+ ## Development
6
+
7
+ ```bash
8
+ bun install
9
+ bun run run:android
10
+ ```
11
+
12
+ The Android command starts Rspeedy, builds and installs the debug APK, verifies
13
+ the ADB reverse tunnel, and launches the app once.
14
+
15
+ To run only the Lynx development server:
16
+
17
+ ```bash
18
+ bun run dev
19
+ ```
20
+
21
+ When the build is ready, scan the printed QR code with the Lynx application on
22
+ the same network to preview the bundle on a device.
23
+
24
+ ## Android App Bundle
25
+
26
+ ```bash
27
+ bun run create:aab
28
+ ```
29
+
30
+ Configure `android/keystore.properties` from the included example before a
31
+ Play Store release. Never commit signing credentials.
32
+
33
+ Application metadata lives in `app.json`. Android is the only supported native
34
+ platform in this phase.