andrud 1.0.0 → 1.0.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 +69 -83
- package/dist/__tests__/context.test.d.ts +5 -0
- package/dist/__tests__/context.test.d.ts.map +1 -0
- package/dist/__tests__/context.test.js +86 -0
- package/dist/__tests__/context.test.js.map +1 -0
- package/dist/__tests__/generator.test.d.ts +5 -0
- package/dist/__tests__/generator.test.d.ts.map +1 -0
- package/dist/__tests__/generator.test.js +83 -0
- package/dist/__tests__/generator.test.js.map +1 -0
- package/dist/__tests__/validation.test.d.ts +5 -0
- package/dist/__tests__/validation.test.d.ts.map +1 -0
- package/dist/__tests__/validation.test.js +81 -0
- package/dist/__tests__/validation.test.js.map +1 -0
- package/dist/cli/commands/create.d.ts +10 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +203 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/info.d.ts +13 -0
- package/dist/cli/commands/info.d.ts.map +1 -0
- package/dist/cli/commands/info.js +153 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/init.d.ts +15 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +141 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +18 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +122 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/new.d.ts +22 -0
- package/dist/cli/commands/new.d.ts.map +1 -0
- package/dist/cli/commands/new.js +245 -0
- package/dist/cli/commands/new.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/config.d.ts +89 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +151 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +47 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +175 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/generator.d.ts +44 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/{src/core/generator.ts → dist/core/generator.js} +394 -484
- package/dist/core/generator.js.map +1 -0
- package/dist/core/types.d.ts +125 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +22 -0
- package/dist/core/types.js.map +1 -0
- package/dist/templates/index.d.ts +36 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +141 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/ui/colors.d.ts +40 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +117 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/output.d.ts +69 -0
- package/dist/ui/output.d.ts.map +1 -0
- package/dist/ui/output.js +199 -0
- package/dist/ui/output.js.map +1 -0
- package/dist/ui/prompts.d.ts +20 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +118 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/ui/spinners.d.ts +30 -0
- package/dist/ui/spinners.d.ts.map +1 -0
- package/dist/ui/spinners.js +74 -0
- package/dist/ui/spinners.js.map +1 -0
- package/dist/ui/types.d.ts +35 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +5 -0
- package/dist/ui/types.js.map +1 -0
- package/dist/utils/filesystem.d.ts +38 -0
- package/dist/utils/filesystem.d.ts.map +1 -0
- package/dist/utils/filesystem.js +181 -0
- package/dist/utils/filesystem.js.map +1 -0
- package/dist/utils/logger.d.ts +27 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/object.d.ts +140 -0
- package/dist/utils/object.d.ts.map +1 -0
- package/dist/utils/object.js +385 -0
- package/dist/utils/object.js.map +1 -0
- package/dist/utils/validation.d.ts +35 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +270 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +8 -19
- package/CHANGELOG.md +0 -70
- package/CODE_REVIEW_ANALYSIS.md +0 -177
- package/CONTRIBUTING.md +0 -132
- package/FIXES_IMPLEMENTED.md +0 -546
- package/src/__tests__/context.test.ts +0 -133
- package/src/__tests__/generator.test.ts +0 -107
- package/src/__tests__/validation.test.ts +0 -105
- package/src/cli/commands/create.ts +0 -252
- package/src/cli/commands/info.ts +0 -178
- package/src/cli/commands/init.ts +0 -186
- package/src/cli/commands/list.ts +0 -156
- package/src/cli/commands/new.ts +0 -316
- package/src/cli/index.ts +0 -116
- package/src/core/config.ts +0 -172
- package/src/core/context.ts +0 -212
- package/src/core/types.ts +0 -184
- package/src/templates/index.ts +0 -162
- package/src/types/gradient-string.d.ts +0 -25
- package/src/ui/colors.ts +0 -139
- package/src/ui/output.ts +0 -230
- package/src/ui/prompts.ts +0 -170
- package/src/ui/spinners.ts +0 -95
- package/src/ui/types.ts +0 -41
- package/src/utils/filesystem.ts +0 -222
- package/src/utils/logger.ts +0 -67
- package/src/utils/object.ts +0 -456
- package/src/utils/validation.ts +0 -345
- package/tsconfig.json +0 -25
package/README.md
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
1
|
# andrud
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img src="https://img.shields.io/npm/v
|
|
5
|
-
<img src="https://img.shields.io/npm/dm
|
|
4
|
+
<a href="https://www.npmjs.com/package/andrud"><img src="https://img.shields.io/npm/v/andrud?style=for-the-badge&color=%2300C9FF&labelColor=%23222" alt="npm version"></a>
|
|
5
|
+
<a href="https://www.npmjs.com/package/andrud"><img src="https://img.shields.io/npm/dm/andrud?style=for-the-badge&color=%2392FE9D&labelColor=%23222" alt="npm downloads"></a>
|
|
6
6
|
<img src="https://img.shields.io/github/license/MurShidM01/andrud?style=for-the-badge&color=%23ff6b6b&labelColor=%23222" alt="license">
|
|
7
|
-
<img src="https://img.shields.io/github/stars/MurShidM01/andrud?style=for-the-badge&color=%23ffd93d&labelColor=%23222" alt="stars">
|
|
8
|
-
<img src="https://img.shields.io/github/forks/MurShidM01/andrud?style=for-the-badge&color=%236bcb77&labelColor=%23222" alt="forks">
|
|
7
|
+
<a href="https://github.com/MurShidM01/andrud/stargazers"><img src="https://img.shields.io/github/stars/MurShidM01/andrud?style=for-the-badge&color=%23ffd93d&labelColor=%23222" alt="stars"></a>
|
|
8
|
+
<a href="https://github.com/MurShidM01/andrud/network/members"><img src="https://img.shields.io/github/forks/MurShidM01/andrud?style=for-the-badge&color=%236bcb77&labelColor=%23222" alt="forks"></a>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<img src="https://img.shields.io/badge/Node.js-
|
|
13
|
-
<img src="https://img.shields.io/badge/TypeScript-5.4-blue?style=for-the-badge&logo=typescript&logoColor=white" alt="typescript">
|
|
14
|
-
<img src="https://img.shields.io/badge/
|
|
15
|
-
<img src="https://img.shields.io/badge/Kotlin-7F52FF?style=for-the-badge&logo=kotlin&logoColor=white" alt="kotlin">
|
|
12
|
+
<a href="https://nodejs.org/"><img src="https://img.shields.io/badge/Node.js-20+-green?style=for-the-badge&logo=node.js&logoColor=white" alt="node"></a>
|
|
13
|
+
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5.4-blue?style=for-the-badge&logo=typescript&logoColor=white" alt="typescript"></a>
|
|
14
|
+
<a href="https://developer.android.com/studio"><img src="https://img.shields.io/badge/Android_Studio-3DDC84?style=for-the-badge&logo=android&logoColor=white" alt="android"></a>
|
|
15
|
+
<a href="https://kotlinlang.org/"><img src="https://img.shields.io/badge/Kotlin-7F52FF?style=for-the-badge&logo=kotlin&logoColor=white" alt="kotlin"></a>
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
|
-
<h1 align="center"
|
|
18
|
+
<h1 align="center">Modern Android Project Scaffolding CLI</h1>
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
21
|
<strong>andrud</strong> is a blazing-fast, interactive CLI tool for generating production-ready Android project structures in seconds. Built for developers who value speed, consistency, and modern Android development practices.
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
25
|
-
<img src="https://
|
|
25
|
+
<img src="https://raw.githubusercontent.com/MurShidM01/andrud/main/sc.png" width="800" alt="andrud demo">
|
|
26
26
|
</p>
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Features
|
|
31
31
|
|
|
32
32
|
| Feature | Description |
|
|
33
33
|
|---------|-------------|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
34
|
+
| Blazing Fast | Generate complete Android projects in under 5 seconds |
|
|
35
|
+
| Multiple Templates | Kotlin, Java, Jetpack Compose, Native C++/NDK support |
|
|
36
|
+
| Interactive CLI | Beautiful prompts powered by @clack/prompts |
|
|
37
|
+
| Production Ready | Industry-standard Gradle configuration with latest versions |
|
|
38
|
+
| TypeScript | Fully typed codebase for reliability |
|
|
39
|
+
| Customizable | Configure SDK versions, features, and more |
|
|
40
|
+
| Modern Android | Android 15 (SDK 35/36) with Jetpack libraries |
|
|
41
|
+
| Beautiful UI | Colorful terminal output with gradients |
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
45
|
-
##
|
|
45
|
+
## Templates
|
|
46
46
|
|
|
47
47
|
| Template | Language | UI Framework | Use Case |
|
|
48
48
|
|----------|----------|--------------|----------|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
49
|
+
| kotlin-xml | Kotlin | XML Views | Traditional Android development |
|
|
50
|
+
| kotlin-compose | Kotlin | Jetpack Compose | Modern declarative UI |
|
|
51
|
+
| java-xml | Java | XML Views | Java projects & legacy codebases |
|
|
52
|
+
| native-cpp | Kotlin + C++ | XML Views | High-performance & game development |
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
-
##
|
|
56
|
+
## Quick Start
|
|
57
57
|
|
|
58
58
|
### Installation
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
# Install globally via npm
|
|
62
|
-
npm install -g
|
|
62
|
+
npm install -g andrud
|
|
63
63
|
|
|
64
64
|
# Verify installation
|
|
65
65
|
andrud --version
|
|
@@ -82,14 +82,14 @@ andrud new MyApp
|
|
|
82
82
|
|
|
83
83
|
| Command | Description |
|
|
84
84
|
|---------|-------------|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
85
|
+
| andrud create | Interactive project creation |
|
|
86
|
+
| andrud new name | Create project with name |
|
|
87
|
+
| andrud list | Show all available templates |
|
|
88
|
+
| andrud info template | View template details |
|
|
89
89
|
|
|
90
90
|
---
|
|
91
91
|
|
|
92
|
-
##
|
|
92
|
+
## Usage Examples
|
|
93
93
|
|
|
94
94
|
### Interactive Project Creation
|
|
95
95
|
|
|
@@ -101,8 +101,8 @@ $ andrud create
|
|
|
101
101
|
? Select template: kotlin-compose
|
|
102
102
|
? Project directory: ./projects
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
Generating project structure...
|
|
105
|
+
MyAwesomeApp created successfully!
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
### Create with Options
|
|
@@ -126,9 +126,9 @@ andrud new MyNativeApp -t native-cpp -p com.mydomain.app
|
|
|
126
126
|
```bash
|
|
127
127
|
$ andrud list
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
+----------------------------------------------------------+
|
|
130
|
+
| Android Project Templates |
|
|
131
|
+
+----------------------------------------------------------+
|
|
132
132
|
|
|
133
133
|
1. Kotlin with XML Layouts
|
|
134
134
|
Traditional Android Views with Kotlin...
|
|
@@ -145,7 +145,7 @@ $ andrud list
|
|
|
145
145
|
|
|
146
146
|
---
|
|
147
147
|
|
|
148
|
-
##
|
|
148
|
+
## Project Structure
|
|
149
149
|
|
|
150
150
|
Generated projects include:
|
|
151
151
|
|
|
@@ -169,7 +169,7 @@ MyApp/
|
|
|
169
169
|
|
|
170
170
|
---
|
|
171
171
|
|
|
172
|
-
##
|
|
172
|
+
## Configuration
|
|
173
173
|
|
|
174
174
|
### SDK Versions
|
|
175
175
|
|
|
@@ -190,7 +190,7 @@ andrud new MyApp --skip-install
|
|
|
190
190
|
|
|
191
191
|
---
|
|
192
192
|
|
|
193
|
-
##
|
|
193
|
+
## Development
|
|
194
194
|
|
|
195
195
|
### Setup
|
|
196
196
|
|
|
@@ -213,31 +213,28 @@ npm run dev -- create
|
|
|
213
213
|
|
|
214
214
|
| Script | Description |
|
|
215
215
|
|--------|-------------|
|
|
216
|
-
|
|
|
217
|
-
|
|
|
218
|
-
|
|
|
219
|
-
|
|
|
216
|
+
| npm run build | Build TypeScript to JavaScript |
|
|
217
|
+
| npm run dev | Build and run in development |
|
|
218
|
+
| npm run link | Link package globally for testing |
|
|
219
|
+
| npm test | Run tests |
|
|
220
220
|
|
|
221
221
|
---
|
|
222
222
|
|
|
223
|
-
##
|
|
223
|
+
## Dependencies
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
### Dev Dependencies
|
|
235
|
-
- **TypeScript 5.4** - Type safety
|
|
236
|
-
- **@types/node** - Node.js type definitions
|
|
225
|
+
| Package | Purpose |
|
|
226
|
+
|---------|---------|
|
|
227
|
+
| @clack/prompts | Beautiful interactive prompts |
|
|
228
|
+
| cac | Lightweight CLI argument parser |
|
|
229
|
+
| fs-extra | Enhanced file system operations |
|
|
230
|
+
| ora | Elegant terminal spinners |
|
|
231
|
+
| picocolors | Terminal colors |
|
|
232
|
+
| gradient-string | Gradient text effects |
|
|
233
|
+
| update-notifier | Check for updates |
|
|
237
234
|
|
|
238
235
|
---
|
|
239
236
|
|
|
240
|
-
##
|
|
237
|
+
## Tech Stack
|
|
241
238
|
|
|
242
239
|
<p align="center">
|
|
243
240
|
<img src="https://skillicons.dev/icons?i=nodejs,typescript,androidstudio,kotlin,gradle,npm" alt="Tech Stack">
|
|
@@ -245,59 +242,48 @@ npm run dev -- create
|
|
|
245
242
|
|
|
246
243
|
---
|
|
247
244
|
|
|
248
|
-
##
|
|
249
|
-
|
|
250
|
-
<p align="center">
|
|
251
|
-
<img src="https://img.shields.io/github/repo-size/MurShidM01/andrud?style=for-the-badge" alt="repo size">
|
|
252
|
-
<img src="https://img.shields.io/github/languages/code-size/MurShidM01/andrud?style=for-the-badge" alt="code size">
|
|
253
|
-
<img src="https://img.shields.io/github/languages/count/MurShidM01/andrud?style=for-the-badge" alt="languages">
|
|
254
|
-
<img src="https://img.shields.io/tokei/lines/github/MurShidM01/andrud?style=for-the-badge" alt="lines of code">
|
|
255
|
-
</p>
|
|
256
|
-
|
|
257
|
-
---
|
|
258
|
-
|
|
259
|
-
## 🤝 Contributing
|
|
245
|
+
## Contributing
|
|
260
246
|
|
|
261
247
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
262
248
|
|
|
263
249
|
1. Fork the repository
|
|
264
|
-
2. Create your feature branch (
|
|
265
|
-
3. Commit your changes (
|
|
266
|
-
4. Push to the branch (
|
|
250
|
+
2. Create your feature branch (git checkout -b feature/amazing-feature)
|
|
251
|
+
3. Commit your changes (git commit -m 'Add amazing feature')
|
|
252
|
+
4. Push to the branch (git push origin feature/amazing-feature)
|
|
267
253
|
5. Open a Pull Request
|
|
268
254
|
|
|
269
255
|
---
|
|
270
256
|
|
|
271
|
-
##
|
|
257
|
+
## License
|
|
272
258
|
|
|
273
|
-
This project is licensed under the MIT License - see the
|
|
259
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
274
260
|
|
|
275
261
|
---
|
|
276
262
|
|
|
277
|
-
##
|
|
263
|
+
## Acknowledgments
|
|
278
264
|
|
|
279
|
-
-
|
|
280
|
-
-
|
|
281
|
-
-
|
|
282
|
-
-
|
|
265
|
+
- Android Open Source Project
|
|
266
|
+
- Jetpack Compose
|
|
267
|
+
- Kotlin
|
|
268
|
+
- Gradle
|
|
283
269
|
|
|
284
270
|
---
|
|
285
271
|
|
|
286
|
-
##
|
|
272
|
+
## Contact
|
|
287
273
|
|
|
288
274
|
<p align="center">
|
|
289
275
|
<a href="https://github.com/MurShidM01/andrud/issues">
|
|
290
276
|
<img src="https://img.shields.io/badge/Issues-Open-green?style=for-the-badge&logo=github" alt="issues">
|
|
291
277
|
</a>
|
|
292
278
|
<a href="https://github.com/MurShidM01/andrud/discussions">
|
|
293
|
-
<img src="https://img.shields.io/badge/Discussions-Q
|
|
279
|
+
<img src="https://img.shields.io/badge/Discussions-Q%26A-blue?style=for-the-badge&logo=github" alt="discussions">
|
|
294
280
|
</a>
|
|
295
281
|
</p>
|
|
296
282
|
|
|
297
283
|
---
|
|
298
284
|
|
|
299
285
|
<p align="center">
|
|
300
|
-
<strong>Made with
|
|
286
|
+
<strong>Made with love by <a href="https://github.com/MurShidM01">MurShidM01</a></strong>
|
|
301
287
|
</p>
|
|
302
288
|
|
|
303
289
|
<p align="center">
|
|
@@ -306,5 +292,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
306
292
|
</p>
|
|
307
293
|
|
|
308
294
|
<p align="center">
|
|
309
|
-
|
|
295
|
+
Star this repo if you find it useful!
|
|
310
296
|
</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/context.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test suite for context builder
|
|
3
|
+
*/
|
|
4
|
+
import { test } from 'node:test';
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
import { buildDefaultProjectContext, buildTemplateContext, validateContext } from '../core/context.js';
|
|
7
|
+
test('Context - Build Default Context', async (t) => {
|
|
8
|
+
await t.test('should create valid default context', () => {
|
|
9
|
+
const context = buildDefaultProjectContext('MyApp', 'com.example.myapp', './my-project', 'kotlin-compose', { git: true, readme: true });
|
|
10
|
+
assert.strictEqual(context.appName, 'MyApp');
|
|
11
|
+
assert.strictEqual(context.packageName, 'com.example.myapp');
|
|
12
|
+
assert.strictEqual(context.template, 'kotlin-compose');
|
|
13
|
+
assert.strictEqual(context.language, 'kotlin');
|
|
14
|
+
assert.strictEqual(context.uiFramework, 'compose');
|
|
15
|
+
});
|
|
16
|
+
await t.test('should set default features', () => {
|
|
17
|
+
const context = buildDefaultProjectContext('MyApp', 'com.example.myapp', './my-project', 'kotlin-xml');
|
|
18
|
+
assert.strictEqual(context.git, true);
|
|
19
|
+
assert.strictEqual(context.readme, true);
|
|
20
|
+
assert.strictEqual(context.androidX, true);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
test('Context - Build Template Context', async (t) => {
|
|
24
|
+
await t.test('should build full template context', () => {
|
|
25
|
+
const baseContext = buildDefaultProjectContext('MyApp', 'com.example.myapp', './my-project', 'kotlin-compose');
|
|
26
|
+
const context = buildTemplateContext({
|
|
27
|
+
appName: baseContext.appName,
|
|
28
|
+
packageName: baseContext.packageName,
|
|
29
|
+
projectDirectory: baseContext.projectDirectory,
|
|
30
|
+
template: baseContext.template,
|
|
31
|
+
uiFramework: baseContext.uiFramework,
|
|
32
|
+
language: baseContext.language,
|
|
33
|
+
android: baseContext.android,
|
|
34
|
+
gradle: baseContext.gradle,
|
|
35
|
+
features: baseContext
|
|
36
|
+
});
|
|
37
|
+
assert.ok(context.appNameCamel);
|
|
38
|
+
assert.ok(context.appNamePascal);
|
|
39
|
+
assert.ok(context.appNameKebab);
|
|
40
|
+
assert.ok(context.appNameSnake);
|
|
41
|
+
assert.ok(context.packagePath);
|
|
42
|
+
assert.ok(context.year);
|
|
43
|
+
assert.ok(context.generatorVersion);
|
|
44
|
+
});
|
|
45
|
+
await t.test('should generate correct app name transformations', () => {
|
|
46
|
+
const baseContext = buildDefaultProjectContext('MyAwesomeApp', 'com.example.myapp', './my-project', 'kotlin-compose');
|
|
47
|
+
const context = buildTemplateContext({
|
|
48
|
+
appName: baseContext.appName,
|
|
49
|
+
packageName: baseContext.packageName,
|
|
50
|
+
projectDirectory: baseContext.projectDirectory,
|
|
51
|
+
template: baseContext.template,
|
|
52
|
+
uiFramework: baseContext.uiFramework,
|
|
53
|
+
language: baseContext.language,
|
|
54
|
+
android: baseContext.android,
|
|
55
|
+
gradle: baseContext.gradle,
|
|
56
|
+
features: baseContext
|
|
57
|
+
});
|
|
58
|
+
assert.ok(context.appNamePascal.includes('Awesome'));
|
|
59
|
+
assert.ok(context.packagePath.includes('/'));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
test('Context - Validate Context', async (t) => {
|
|
63
|
+
await t.test('should accept valid context', () => {
|
|
64
|
+
const baseContext = buildDefaultProjectContext('MyApp', 'com.example.myapp', './my-project', 'kotlin-compose');
|
|
65
|
+
const result = validateContext(baseContext);
|
|
66
|
+
assert.strictEqual(result.valid, true);
|
|
67
|
+
});
|
|
68
|
+
await t.test('should reject context with missing appName', () => {
|
|
69
|
+
const result = validateContext({
|
|
70
|
+
appName: '',
|
|
71
|
+
packageName: 'com.example.myapp',
|
|
72
|
+
template: 'kotlin-compose'
|
|
73
|
+
});
|
|
74
|
+
assert.strictEqual(result.valid, false);
|
|
75
|
+
assert.ok(result.errors.length > 0);
|
|
76
|
+
});
|
|
77
|
+
await t.test('should reject context with missing packageName', () => {
|
|
78
|
+
const result = validateContext({
|
|
79
|
+
appName: 'MyApp',
|
|
80
|
+
packageName: '',
|
|
81
|
+
template: 'kotlin-compose'
|
|
82
|
+
});
|
|
83
|
+
assert.strictEqual(result.valid, false);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=context.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.test.js","sourceRoot":"","sources":["../../src/__tests__/context.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAG5B,IAAI,CAAC,iCAAiC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAClD,MAAM,CAAC,CAAC,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE;QACvD,MAAM,OAAO,GAAG,0BAA0B,CACxC,OAAO,EACP,mBAAmB,EACnB,cAAc,EACd,gBAAgC,EAChC,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAC5B,CAAC;QAEF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QACvD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC/C,MAAM,OAAO,GAAG,0BAA0B,CACxC,OAAO,EACP,mBAAmB,EACnB,cAAc,EACd,YAA4B,CAC7B,CAAC;QAEF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kCAAkC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnD,MAAM,CAAC,CAAC,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE;QACtD,MAAM,WAAW,GAAG,0BAA0B,CAC5C,OAAO,EACP,mBAAmB,EACnB,cAAc,EACd,gBAAgC,CACjC,CAAC;QAEF,MAAM,OAAO,GAAG,oBAAoB,CAAC;YACnC,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;YAC9C,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,QAAQ,EAAE,WAAiD;SAC5D,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACjC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC/B,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,CAAC,IAAI,CAAC,kDAAkD,EAAE,GAAG,EAAE;QACpE,MAAM,WAAW,GAAG,0BAA0B,CAC5C,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,gBAAgC,CACjC,CAAC;QAEF,MAAM,OAAO,GAAG,oBAAoB,CAAC;YACnC,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;YAC9C,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,QAAQ,EAAE,WAAiD;SAC5D,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4BAA4B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7C,MAAM,CAAC,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC/C,MAAM,WAAW,GAAG,0BAA0B,CAC5C,OAAO,EACP,mBAAmB,EACnB,cAAc,EACd,gBAAgC,CACjC,CAAC;QAEF,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC5C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,CAAC,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QAC9D,MAAM,MAAM,GAAG,eAAe,CAAC;YAC7B,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,mBAAmB;YAChC,QAAQ,EAAE,gBAAgC;SAC3C,CAAC,CAAC;QAEH,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,CAAC,IAAI,CAAC,gDAAgD,EAAE,GAAG,EAAE;QAClE,MAAM,MAAM,GAAG,eAAe,CAAC;YAC7B,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,EAAE;YACf,QAAQ,EAAE,gBAAgC;SAC3C,CAAC,CAAC;QAEH,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/generator.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test suite for generator utilities
|
|
3
|
+
*/
|
|
4
|
+
import { test } from 'node:test';
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
import { validateContext, validateProjectDirectory } from '../core/generator.js';
|
|
7
|
+
test('Generator - Validate Context', async (t) => {
|
|
8
|
+
await t.test('should accept valid context', () => {
|
|
9
|
+
const context = {
|
|
10
|
+
appName: 'MyApp',
|
|
11
|
+
packageName: 'com.example.myapp',
|
|
12
|
+
projectDirectory: './my-project',
|
|
13
|
+
template: 'kotlin-compose',
|
|
14
|
+
language: 'kotlin',
|
|
15
|
+
uiFramework: 'compose',
|
|
16
|
+
android: {
|
|
17
|
+
minSdk: 31,
|
|
18
|
+
targetSdk: 36,
|
|
19
|
+
compileSdk: 36
|
|
20
|
+
},
|
|
21
|
+
gradle: {
|
|
22
|
+
agpVersion: '8.7.3',
|
|
23
|
+
gradleVersion: '8.14',
|
|
24
|
+
kotlinVersion: '2.0.21'
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const result = validateContext(context);
|
|
28
|
+
assert.strictEqual(result.valid, true);
|
|
29
|
+
});
|
|
30
|
+
await t.test('should reject context with missing appName', () => {
|
|
31
|
+
const context = {
|
|
32
|
+
appName: '',
|
|
33
|
+
packageName: 'com.example.myapp'
|
|
34
|
+
};
|
|
35
|
+
const result = validateContext(context);
|
|
36
|
+
assert.strictEqual(result.valid, false);
|
|
37
|
+
assert.ok(result.errors.some(e => e.includes('appName')));
|
|
38
|
+
});
|
|
39
|
+
await t.test('should reject context with missing packageName', () => {
|
|
40
|
+
const context = {
|
|
41
|
+
appName: 'MyApp',
|
|
42
|
+
packageName: ''
|
|
43
|
+
};
|
|
44
|
+
const result = validateContext(context);
|
|
45
|
+
assert.strictEqual(result.valid, false);
|
|
46
|
+
assert.ok(result.errors.some(e => e.includes('packageName')));
|
|
47
|
+
});
|
|
48
|
+
await t.test('should reject context with missing template', () => {
|
|
49
|
+
const context = {
|
|
50
|
+
appName: 'MyApp',
|
|
51
|
+
packageName: 'com.example.myapp',
|
|
52
|
+
template: undefined
|
|
53
|
+
};
|
|
54
|
+
const result = validateContext(context);
|
|
55
|
+
assert.strictEqual(result.valid, false);
|
|
56
|
+
assert.ok(result.errors.some(e => e.includes('template')));
|
|
57
|
+
});
|
|
58
|
+
await t.test('should reject context with missing language', () => {
|
|
59
|
+
const context = {
|
|
60
|
+
appName: 'MyApp',
|
|
61
|
+
packageName: 'com.example.myapp',
|
|
62
|
+
template: 'kotlin-compose',
|
|
63
|
+
language: undefined
|
|
64
|
+
};
|
|
65
|
+
const result = validateContext(context);
|
|
66
|
+
assert.strictEqual(result.valid, false);
|
|
67
|
+
assert.ok(result.errors.some(e => e.includes('language')));
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
test('Generator - Validate Project Directory', async (t) => {
|
|
71
|
+
await t.test('should validate non-existent directory', async () => {
|
|
72
|
+
const result = await validateProjectDirectory('/tmp/nonexistent-dir-' + Date.now(), { overwrite: false });
|
|
73
|
+
assert.strictEqual(result.valid, true);
|
|
74
|
+
});
|
|
75
|
+
await t.test('should allow non-empty directory with overwrite', async () => {
|
|
76
|
+
// Note: This would require actual file system operations
|
|
77
|
+
// In a real test, we'd mock the filesystem
|
|
78
|
+
const result = await validateProjectDirectory('/tmp/test-dir', { overwrite: true });
|
|
79
|
+
// Just assert the result has the expected shape
|
|
80
|
+
assert.ok(typeof result.valid === 'boolean');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=generator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.test.js","sourceRoot":"","sources":["../../src/__tests__/generator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/validation.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test suite for validation utilities
|
|
3
|
+
*/
|
|
4
|
+
import { test } from 'node:test';
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
import { validateAppName, validatePackageNameInput, validateDirectoryPath, camelCase, pascalCase, kebabCase, snakeCase } from '../utils/validation.js';
|
|
7
|
+
test('Validation - App Name', async (t) => {
|
|
8
|
+
await t.test('should accept valid app name', () => {
|
|
9
|
+
const result = validateAppName('MyAwesomeApp');
|
|
10
|
+
assert.strictEqual(result.valid, true);
|
|
11
|
+
});
|
|
12
|
+
await t.test('should reject app name starting with number', () => {
|
|
13
|
+
const result = validateAppName('1App');
|
|
14
|
+
assert.strictEqual(result.valid, false);
|
|
15
|
+
assert.ok(result.errors.length > 0);
|
|
16
|
+
});
|
|
17
|
+
await t.test('should reject app name with spaces', () => {
|
|
18
|
+
const result = validateAppName('My App');
|
|
19
|
+
assert.strictEqual(result.valid, false);
|
|
20
|
+
});
|
|
21
|
+
await t.test('should reject empty app name', () => {
|
|
22
|
+
const result = validateAppName('');
|
|
23
|
+
assert.strictEqual(result.valid, false);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
test('Validation - Package Name', async (t) => {
|
|
27
|
+
await t.test('should accept valid package name', () => {
|
|
28
|
+
const result = validatePackageNameInput('com.example.myapp');
|
|
29
|
+
assert.strictEqual(result.valid, true);
|
|
30
|
+
});
|
|
31
|
+
await t.test('should reject reserved prefix android', () => {
|
|
32
|
+
const result = validatePackageNameInput('android.example.app');
|
|
33
|
+
assert.strictEqual(result.valid, false);
|
|
34
|
+
});
|
|
35
|
+
await t.test('should reject reserved prefix kotlin', () => {
|
|
36
|
+
const result = validatePackageNameInput('kotlin.example.app');
|
|
37
|
+
assert.strictEqual(result.valid, false);
|
|
38
|
+
});
|
|
39
|
+
await t.test('should reject package with single segment', () => {
|
|
40
|
+
const result = validatePackageNameInput('myapp');
|
|
41
|
+
assert.strictEqual(result.valid, false);
|
|
42
|
+
});
|
|
43
|
+
await t.test('should warn on generic com.example prefix', () => {
|
|
44
|
+
const result = validatePackageNameInput('com.example.app');
|
|
45
|
+
assert.strictEqual(result.valid, true);
|
|
46
|
+
assert.ok(result.warnings && result.warnings.length > 0);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
test('Validation - Directory Path', async (t) => {
|
|
50
|
+
await t.test('should accept valid directory path', () => {
|
|
51
|
+
const result = validateDirectoryPath('./my-project');
|
|
52
|
+
assert.strictEqual(result.valid, true);
|
|
53
|
+
});
|
|
54
|
+
await t.test('should reject empty directory path', () => {
|
|
55
|
+
const result = validateDirectoryPath('');
|
|
56
|
+
assert.strictEqual(result.valid, false);
|
|
57
|
+
});
|
|
58
|
+
await t.test('should reject directory traversal', () => {
|
|
59
|
+
const result = validateDirectoryPath('../../../etc/passwd');
|
|
60
|
+
assert.strictEqual(result.valid, false);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
test('String Case Transformations', async (t) => {
|
|
64
|
+
await t.test('camelCase should transform correctly', () => {
|
|
65
|
+
const result = camelCase('my awesome app');
|
|
66
|
+
assert.strictEqual(result, 'myAwesomeApp');
|
|
67
|
+
});
|
|
68
|
+
await t.test('pascalCase should transform correctly', () => {
|
|
69
|
+
const result = pascalCase('my awesome app');
|
|
70
|
+
assert.strictEqual(result, 'MyAwesomeApp');
|
|
71
|
+
});
|
|
72
|
+
await t.test('kebabCase should transform correctly', () => {
|
|
73
|
+
const result = kebabCase('my awesome app');
|
|
74
|
+
assert.strictEqual(result, 'my-awesome-app');
|
|
75
|
+
});
|
|
76
|
+
await t.test('snakeCase should transform correctly', () => {
|
|
77
|
+
const result = snakeCase('my awesome app');
|
|
78
|
+
assert.strictEqual(result, 'my_awesome_app');
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=validation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.test.js","sourceRoot":"","sources":["../../src/__tests__/validation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean, minimal Vite-style project creation command
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Create a new Android project with clean minimal UI
|
|
6
|
+
*/
|
|
7
|
+
export declare function createCommand(options?: {
|
|
8
|
+
force?: boolean;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6CH;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAyMpF"}
|