andrud 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.
- package/README.md +295 -306
- 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 +157 -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 +10 -21
- package/CHANGELOG.md +0 -70
- package/CONTRIBUTING.md +0 -132
- package/sc.png +0 -0
- 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
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation utilities for app names, package names, and paths
|
|
3
|
+
*/
|
|
4
|
+
// Validate app name
|
|
5
|
+
export function validateAppName(name) {
|
|
6
|
+
const errors = [];
|
|
7
|
+
const warnings = [];
|
|
8
|
+
if (!name || name.trim().length === 0) {
|
|
9
|
+
errors.push('App name cannot be empty');
|
|
10
|
+
return { valid: false, errors, warnings };
|
|
11
|
+
}
|
|
12
|
+
const trimmed = name.trim();
|
|
13
|
+
// Check for invalid characters
|
|
14
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(trimmed)) {
|
|
15
|
+
if (trimmed.includes('-')) {
|
|
16
|
+
errors.push('App name cannot contain hyphens. Use underscores instead (e.g., My_Awesome_App)');
|
|
17
|
+
}
|
|
18
|
+
else if (trimmed.includes(' ')) {
|
|
19
|
+
errors.push('App name cannot contain spaces. Use underscores instead (e.g., My_Awesome_App)');
|
|
20
|
+
}
|
|
21
|
+
else if (/^[0-9]/.test(trimmed)) {
|
|
22
|
+
errors.push('App name must start with a letter');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
errors.push('App name can only contain letters, numbers, and underscores');
|
|
26
|
+
}
|
|
27
|
+
return { valid: false, errors, warnings };
|
|
28
|
+
}
|
|
29
|
+
// Warnings for reserved words
|
|
30
|
+
const reservedWords = ['android', 'app', 'application', 'com', 'org', 'net', 'io', 'java', 'kotlin'];
|
|
31
|
+
if (reservedWords.includes(trimmed.toLowerCase())) {
|
|
32
|
+
warnings.push(`"${trimmed}" is a common word. Consider a more unique app name.`);
|
|
33
|
+
}
|
|
34
|
+
// Check length
|
|
35
|
+
if (trimmed.length < 3) {
|
|
36
|
+
warnings.push('App name is very short. Consider using a more descriptive name.');
|
|
37
|
+
}
|
|
38
|
+
if (trimmed.length > 50) {
|
|
39
|
+
errors.push('App name cannot exceed 50 characters');
|
|
40
|
+
return { valid: false, errors, warnings };
|
|
41
|
+
}
|
|
42
|
+
// Normalize (capitalize first letter)
|
|
43
|
+
const normalized = trimmed.charAt(0).toUpperCase() + trimmed.slice(1);
|
|
44
|
+
return { valid: true, errors, warnings, normalized };
|
|
45
|
+
}
|
|
46
|
+
// Validate package name input
|
|
47
|
+
export function validatePackageNameInput(name) {
|
|
48
|
+
const errors = [];
|
|
49
|
+
const warnings = [];
|
|
50
|
+
const suggestions = [];
|
|
51
|
+
if (!name || name.trim().length === 0) {
|
|
52
|
+
errors.push('Package name cannot be empty');
|
|
53
|
+
return { valid: false, errors, warnings, suggestions };
|
|
54
|
+
}
|
|
55
|
+
const trimmed = name.trim().toLowerCase();
|
|
56
|
+
// Check basic format
|
|
57
|
+
if (!/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/.test(trimmed)) {
|
|
58
|
+
errors.push('Package name must follow domain structure (e.g., com.example.myapp)');
|
|
59
|
+
errors.push('Each segment must start with a letter and contain only lowercase letters, numbers, and underscores');
|
|
60
|
+
// Generate suggestions
|
|
61
|
+
if (!trimmed.startsWith('com.') && !trimmed.startsWith('org.') && !trimmed.startsWith('io.') && !trimmed.startsWith('net.')) {
|
|
62
|
+
suggestions.push('com.' + trimmed);
|
|
63
|
+
}
|
|
64
|
+
if (trimmed.split('.').length < 2) {
|
|
65
|
+
suggestions.push(trimmed + '.app');
|
|
66
|
+
suggestions.push(trimmed + '.myapp');
|
|
67
|
+
}
|
|
68
|
+
return { valid: false, errors, warnings, suggestions };
|
|
69
|
+
}
|
|
70
|
+
// Minimum 2 segments
|
|
71
|
+
const segments = trimmed.split('.');
|
|
72
|
+
if (segments.length < 2) {
|
|
73
|
+
errors.push('Package name must have at least 2 segments (e.g., com.app)');
|
|
74
|
+
return { valid: false, errors, warnings, suggestions };
|
|
75
|
+
}
|
|
76
|
+
// Maximum segment length
|
|
77
|
+
for (const segment of segments) {
|
|
78
|
+
if (segment.length < 1) {
|
|
79
|
+
errors.push('Package segments cannot be empty');
|
|
80
|
+
return { valid: false, errors, warnings, suggestions };
|
|
81
|
+
}
|
|
82
|
+
if (segment.length > 50) {
|
|
83
|
+
errors.push(`Package segment "${segment}" exceeds 50 character limit`);
|
|
84
|
+
return { valid: false, errors, warnings, suggestions };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Check for reserved prefixes
|
|
88
|
+
const reservedPrefixes = ['java', 'android', 'kotlin', 'javax', 'androidx', 'com.android'];
|
|
89
|
+
if (reservedPrefixes.some(p => trimmed.startsWith(p + '.'))) {
|
|
90
|
+
const prefix = reservedPrefixes.find(p => trimmed.startsWith(p + '.'));
|
|
91
|
+
errors.push(`Package name cannot start with reserved prefix: ${prefix}`);
|
|
92
|
+
return { valid: false, errors, warnings, suggestions };
|
|
93
|
+
}
|
|
94
|
+
// Warnings
|
|
95
|
+
if (segments[0] === 'com' && (segments[1] === 'example' || segments[1] === 'test' || segments[1] === 'app')) {
|
|
96
|
+
warnings.push('Using generic "com.example" prefix. Consider using your own domain.');
|
|
97
|
+
}
|
|
98
|
+
return { valid: true, errors, warnings };
|
|
99
|
+
}
|
|
100
|
+
// Validate package structure (similar to input but for verification)
|
|
101
|
+
export function validatePackageStructure(name) {
|
|
102
|
+
return validatePackageNameInput(name);
|
|
103
|
+
}
|
|
104
|
+
// Validate directory path
|
|
105
|
+
export function validateDirectoryPath(path) {
|
|
106
|
+
const errors = [];
|
|
107
|
+
const warnings = [];
|
|
108
|
+
if (!path || path.trim().length === 0) {
|
|
109
|
+
errors.push('Directory path cannot be empty');
|
|
110
|
+
return { valid: false, errors, warnings };
|
|
111
|
+
}
|
|
112
|
+
const trimmed = path.trim();
|
|
113
|
+
// Check for directory traversal
|
|
114
|
+
if (trimmed.includes('..')) {
|
|
115
|
+
errors.push('Directory path cannot contain ".." to prevent directory traversal');
|
|
116
|
+
return { valid: false, errors, warnings };
|
|
117
|
+
}
|
|
118
|
+
// Allow normal path characters including Windows backslashes
|
|
119
|
+
// Just check for truly invalid characters
|
|
120
|
+
if (/[<>:"|?*]/.test(trimmed)) {
|
|
121
|
+
errors.push('Directory path contains invalid characters');
|
|
122
|
+
return { valid: false, errors, warnings };
|
|
123
|
+
}
|
|
124
|
+
// Check for absolute path
|
|
125
|
+
const isAbsolutePath = /^[A-Za-z]:\\|\//.test(trimmed) || trimmed.startsWith('/');
|
|
126
|
+
// Warn about potential issues
|
|
127
|
+
if (trimmed.includes(' ')) {
|
|
128
|
+
warnings.push('Path contains spaces. This may cause issues with some build tools.');
|
|
129
|
+
}
|
|
130
|
+
if (isAbsolutePath && (trimmed.includes('$') || trimmed.includes('`'))) {
|
|
131
|
+
warnings.push('Path contains special characters that may be interpreted as variables.');
|
|
132
|
+
}
|
|
133
|
+
return { valid: true, errors, warnings, normalized: trimmed };
|
|
134
|
+
}
|
|
135
|
+
// Validate email
|
|
136
|
+
export function validateEmail(email) {
|
|
137
|
+
const errors = [];
|
|
138
|
+
const warnings = [];
|
|
139
|
+
if (!email || email.trim().length === 0) {
|
|
140
|
+
errors.push('Email cannot be empty');
|
|
141
|
+
return { valid: false, errors, warnings };
|
|
142
|
+
}
|
|
143
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
144
|
+
if (!emailRegex.test(email.trim())) {
|
|
145
|
+
errors.push('Invalid email format');
|
|
146
|
+
return { valid: false, errors, warnings };
|
|
147
|
+
}
|
|
148
|
+
return { valid: true, errors, warnings };
|
|
149
|
+
}
|
|
150
|
+
// Validate URL
|
|
151
|
+
export function validateUrl(url) {
|
|
152
|
+
const errors = [];
|
|
153
|
+
const warnings = [];
|
|
154
|
+
if (!url || url.trim().length === 0) {
|
|
155
|
+
errors.push('URL cannot be empty');
|
|
156
|
+
return { valid: false, errors, warnings };
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
new URL(url);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
errors.push('Invalid URL format');
|
|
163
|
+
return { valid: false, errors, warnings };
|
|
164
|
+
}
|
|
165
|
+
return { valid: true, errors, warnings };
|
|
166
|
+
}
|
|
167
|
+
// Validate version string
|
|
168
|
+
export function validateVersion(version) {
|
|
169
|
+
const errors = [];
|
|
170
|
+
const warnings = [];
|
|
171
|
+
if (!version || version.trim().length === 0) {
|
|
172
|
+
errors.push('Version cannot be empty');
|
|
173
|
+
return { valid: false, errors, warnings };
|
|
174
|
+
}
|
|
175
|
+
// Semantic versioning format
|
|
176
|
+
const versionRegex = /^\d+\.\d+(\.\d+)?(-[a-zA-Z0-9.-]+)?$/;
|
|
177
|
+
if (!versionRegex.test(version.trim())) {
|
|
178
|
+
errors.push('Version must follow semantic versioning (e.g., 1.0.0 or 1.0.0-beta)');
|
|
179
|
+
return { valid: false, errors, warnings };
|
|
180
|
+
}
|
|
181
|
+
return { valid: true, errors, warnings };
|
|
182
|
+
}
|
|
183
|
+
// Validate Android min SDK
|
|
184
|
+
export function validateAndroidMinSdk(sdk) {
|
|
185
|
+
const errors = [];
|
|
186
|
+
const warnings = [];
|
|
187
|
+
const sdkNum = typeof sdk === 'string' ? parseInt(sdk, 10) : sdk;
|
|
188
|
+
if (isNaN(sdkNum)) {
|
|
189
|
+
errors.push('Min SDK must be a number');
|
|
190
|
+
return { valid: false, errors, warnings };
|
|
191
|
+
}
|
|
192
|
+
if (sdkNum < 16) {
|
|
193
|
+
errors.push('Min SDK must be at least 16 (Android 4.1)');
|
|
194
|
+
return { valid: false, errors, warnings };
|
|
195
|
+
}
|
|
196
|
+
if (sdkNum > 35) {
|
|
197
|
+
warnings.push('Min SDK is very high. This excludes older devices.');
|
|
198
|
+
}
|
|
199
|
+
return { valid: true, errors, warnings };
|
|
200
|
+
}
|
|
201
|
+
// Validate Android target SDK
|
|
202
|
+
export function validateAndroidTargetSdk(sdk) {
|
|
203
|
+
const errors = [];
|
|
204
|
+
const warnings = [];
|
|
205
|
+
const sdkNum = typeof sdk === 'string' ? parseInt(sdk, 10) : sdk;
|
|
206
|
+
if (isNaN(sdkNum)) {
|
|
207
|
+
errors.push('Target SDK must be a number');
|
|
208
|
+
return { valid: false, errors, warnings };
|
|
209
|
+
}
|
|
210
|
+
if (sdkNum < 21) {
|
|
211
|
+
errors.push('Target SDK must be at least 21');
|
|
212
|
+
return { valid: false, errors, warnings };
|
|
213
|
+
}
|
|
214
|
+
if (sdkNum > 35) {
|
|
215
|
+
warnings.push('Target SDK exceeds latest stable (35). This might require unstable dependencies.');
|
|
216
|
+
}
|
|
217
|
+
return { valid: true, errors, warnings };
|
|
218
|
+
}
|
|
219
|
+
// Sanitize file name
|
|
220
|
+
export function sanitizeFileName(name) {
|
|
221
|
+
return name
|
|
222
|
+
.replace(/[<>:"/\\|?*]/g, '_')
|
|
223
|
+
.replace(/\s+/g, '_')
|
|
224
|
+
.replace(/_{2,}/g, '_')
|
|
225
|
+
.trim();
|
|
226
|
+
}
|
|
227
|
+
// Sanitize package name
|
|
228
|
+
export function sanitizePackageName(name) {
|
|
229
|
+
return name
|
|
230
|
+
.toLowerCase()
|
|
231
|
+
.replace(/[^a-z0-9.]/g, '_')
|
|
232
|
+
.replace(/_{2,}/g, '.')
|
|
233
|
+
.replace(/^\.|\.$/g, '')
|
|
234
|
+
.trim();
|
|
235
|
+
}
|
|
236
|
+
// String transformation utilities
|
|
237
|
+
export function capitalizeFirstLetter(str) {
|
|
238
|
+
if (!str)
|
|
239
|
+
return '';
|
|
240
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
241
|
+
}
|
|
242
|
+
export function camelCase(str) {
|
|
243
|
+
return str
|
|
244
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase())
|
|
245
|
+
.replace(/\s+|_+/g, '');
|
|
246
|
+
}
|
|
247
|
+
export function pascalCase(str) {
|
|
248
|
+
return str
|
|
249
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word) => word.toUpperCase())
|
|
250
|
+
.replace(/\s+|_+/g, '');
|
|
251
|
+
}
|
|
252
|
+
export function kebabCase(str) {
|
|
253
|
+
return str
|
|
254
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
255
|
+
.replace(/\s+|_+/g, '-')
|
|
256
|
+
.toLowerCase();
|
|
257
|
+
}
|
|
258
|
+
export function snakeCase(str) {
|
|
259
|
+
return str
|
|
260
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
261
|
+
.replace(/\s+|-+/g, '_')
|
|
262
|
+
.toLowerCase();
|
|
263
|
+
}
|
|
264
|
+
export function dotCase(str) {
|
|
265
|
+
return str
|
|
266
|
+
.replace(/([a-z])([A-Z])/g, '$1.$2')
|
|
267
|
+
.replace(/\s+|-+|_+/g, '.')
|
|
268
|
+
.toLowerCase();
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
2
|
"name": "andrud",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Modern Android project scaffolding CLI tool - Generate production-ready Android projects in seconds",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"bin",
|
|
9
|
+
"package.json",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
6
13
|
"bin": {
|
|
7
14
|
"andrud": "./bin/andrud.js"
|
|
8
15
|
},
|
|
@@ -22,24 +29,6 @@
|
|
|
22
29
|
"android-studio",
|
|
23
30
|
"mobile-development"
|
|
24
31
|
],
|
|
25
|
-
"exports": {
|
|
26
|
-
".": {
|
|
27
|
-
"types": "./dist/cli/index.d.ts",
|
|
28
|
-
"import": "./dist/cli/index.js"
|
|
29
|
-
},
|
|
30
|
-
"./core": {
|
|
31
|
-
"types": "./dist/core/index.d.ts",
|
|
32
|
-
"import": "./dist/core/index.js"
|
|
33
|
-
},
|
|
34
|
-
"./ui": {
|
|
35
|
-
"types": "./dist/ui/index.d.ts",
|
|
36
|
-
"import": "./dist/ui/index.js"
|
|
37
|
-
},
|
|
38
|
-
"./utils": {
|
|
39
|
-
"types": "./dist/utils/index.d.ts",
|
|
40
|
-
"import": "./dist/utils/index.js"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
32
|
"scripts": {
|
|
44
33
|
"build": "tsc -b",
|
|
45
34
|
"build:all": "tsc -b",
|
|
@@ -77,4 +66,4 @@
|
|
|
77
66
|
"engines": {
|
|
78
67
|
"node": ">=18.0.0"
|
|
79
68
|
}
|
|
80
|
-
}
|
|
69
|
+
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
|
|
8
|
-
## [1.0.0] - 2026-05-31
|
|
9
|
-
|
|
10
|
-
### 🎉 Initial Release
|
|
11
|
-
|
|
12
|
-
#### Added
|
|
13
|
-
- **4 Project Templates**:
|
|
14
|
-
- `kotlin-xml` - Kotlin with XML Views
|
|
15
|
-
- `kotlin-compose` - Kotlin with Jetpack Compose
|
|
16
|
-
- `java-xml` - Java with XML Views
|
|
17
|
-
- `native-cpp` - Kotlin with Native C++/NDK support
|
|
18
|
-
|
|
19
|
-
- **CLI Commands**:
|
|
20
|
-
- `andrud create` - Interactive project creation
|
|
21
|
-
- `andrud new <name>` - Quick project creation
|
|
22
|
-
- `andrud list` - List all templates
|
|
23
|
-
- `andrud info <template>` - View template details
|
|
24
|
-
|
|
25
|
-
- **Features**:
|
|
26
|
-
- Beautiful interactive prompts with @clack/prompts
|
|
27
|
-
- Colorful terminal output with gradients
|
|
28
|
-
- Production-ready Gradle configurations
|
|
29
|
-
- Android 15/16 (SDK 35/36) support
|
|
30
|
-
- Latest Jetpack libraries integration
|
|
31
|
-
- Material Design 3 support
|
|
32
|
-
- ViewBinding and DataBinding support
|
|
33
|
-
- Jetpack Compose support
|
|
34
|
-
- Native C++/NDK integration
|
|
35
|
-
- Gradle wrapper generation
|
|
36
|
-
- .gitignore generation
|
|
37
|
-
- README.md generation
|
|
38
|
-
|
|
39
|
-
#### Technical
|
|
40
|
-
- Built with TypeScript 5.4
|
|
41
|
-
- Node.js 18+ required
|
|
42
|
-
- ES Modules (ESM) support
|
|
43
|
-
- Full type safety
|
|
44
|
-
- Comprehensive validation utilities
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## [Unreleased]
|
|
49
|
-
|
|
50
|
-
### Planned Features
|
|
51
|
-
- [ ] Template customization options
|
|
52
|
-
- [ ] Plugin system for custom generators
|
|
53
|
-
- [ ] Progress reporting for large projects
|
|
54
|
-
- [ ] Dry-run mode
|
|
55
|
-
- [ ] Git initialization option
|
|
56
|
-
- [ ] Configuration file support (andrud.config.js)
|
|
57
|
-
- [ ] Interactive mode with --interactive flag
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Version History
|
|
62
|
-
|
|
63
|
-
| Version | Status | Date |
|
|
64
|
-
|---------|--------|------|
|
|
65
|
-
| 1.0.0 | ✅ Current | 2026-05-31 |
|
|
66
|
-
| 0.0.1 | 🔧 Development | 2026-05-28 |
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
**Note**: Initial release marks the first stable version of andrud CLI.
|
package/CONTRIBUTING.md
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# Contributing to andrud
|
|
2
|
-
|
|
3
|
-
Thank you for your interest in contributing to **andrud**! 🎉
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 🤝 How to Contribute
|
|
8
|
-
|
|
9
|
-
### 1. Reporting Issues
|
|
10
|
-
|
|
11
|
-
Found a bug or have a feature request? Please [open an issue](https://github.com/MurShidM01/andrud/issues) with:
|
|
12
|
-
|
|
13
|
-
- Clear description of the issue/feature
|
|
14
|
-
- Steps to reproduce (for bugs)
|
|
15
|
-
- Expected vs actual behavior
|
|
16
|
-
- Your environment (Node.js version, OS, etc.)
|
|
17
|
-
|
|
18
|
-
### 2. Pull Requests
|
|
19
|
-
|
|
20
|
-
1. **Fork** the repository
|
|
21
|
-
2. **Clone** your fork:
|
|
22
|
-
```bash
|
|
23
|
-
git clone https://github.com/YOUR_USERNAME/andrud.git
|
|
24
|
-
cd andrud
|
|
25
|
-
```
|
|
26
|
-
3. **Create** a feature branch:
|
|
27
|
-
```bash
|
|
28
|
-
git checkout -b feature/your-feature-name
|
|
29
|
-
```
|
|
30
|
-
4. **Install** dependencies:
|
|
31
|
-
```bash
|
|
32
|
-
npm install
|
|
33
|
-
```
|
|
34
|
-
5. **Make** your changes
|
|
35
|
-
6. **Build** and test:
|
|
36
|
-
```bash
|
|
37
|
-
npm run build
|
|
38
|
-
npm run dev -- list
|
|
39
|
-
```
|
|
40
|
-
7. **Commit** your changes:
|
|
41
|
-
```bash
|
|
42
|
-
git commit -m "Add: your feature description"
|
|
43
|
-
```
|
|
44
|
-
8. **Push** to your fork:
|
|
45
|
-
```bash
|
|
46
|
-
git push origin feature/your-feature-name
|
|
47
|
-
```
|
|
48
|
-
9. **Open** a Pull Request
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## 📋 Development Setup
|
|
53
|
-
|
|
54
|
-
### Prerequisites
|
|
55
|
-
|
|
56
|
-
- Node.js 18+
|
|
57
|
-
- npm 9+
|
|
58
|
-
|
|
59
|
-
### Quick Start
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# Clone repo
|
|
63
|
-
git clone https://github.com/MurShidM01/andrud.git
|
|
64
|
-
cd andrud
|
|
65
|
-
|
|
66
|
-
# Install dependencies
|
|
67
|
-
npm install
|
|
68
|
-
|
|
69
|
-
# Build project
|
|
70
|
-
npm run build
|
|
71
|
-
|
|
72
|
-
# Run in dev mode
|
|
73
|
-
npm run dev -- create
|
|
74
|
-
|
|
75
|
-
# Link for global testing
|
|
76
|
-
npm run link
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## 🧪 Testing
|
|
82
|
-
|
|
83
|
-
Before submitting a PR, please test your changes:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
# Test all commands
|
|
87
|
-
npm run dev -- --help
|
|
88
|
-
npm run dev -- list
|
|
89
|
-
npm run dev -- info kotlin-compose
|
|
90
|
-
|
|
91
|
-
# Create a test project
|
|
92
|
-
cd /tmp
|
|
93
|
-
npm run dev -- new TestApp -t kotlin-xml -p com.test.app
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## 📐 Code Style
|
|
99
|
-
|
|
100
|
-
- Use **TypeScript** for all new code
|
|
101
|
-
- Follow existing code patterns
|
|
102
|
-
- Add types for new functions
|
|
103
|
-
- Keep functions small and focused
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## 🔍 Code Review Process
|
|
108
|
-
|
|
109
|
-
All PRs will be reviewed by the maintainer. Please ensure:
|
|
110
|
-
|
|
111
|
-
- [ ] Code builds without errors
|
|
112
|
-
- [ ] Tests pass (if applicable)
|
|
113
|
-
- [ ] No new TypeScript errors introduced
|
|
114
|
-
- [ ] Changes are minimal and focused
|
|
115
|
-
- [ ] Commit messages are descriptive
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## 📜 License
|
|
120
|
-
|
|
121
|
-
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
## 💬 Need Help?
|
|
126
|
-
|
|
127
|
-
- Open a [discussion](https://github.com/MurShidM01/andrud/discussions)
|
|
128
|
-
- Check [existing issues](https://github.com/MurShidM01/andrud/issues)
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
**Happy coding!** 🚀
|
package/sc.png
DELETED
|
Binary file
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test suite for context builder
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { test } from 'node:test';
|
|
6
|
-
import assert from 'node:assert';
|
|
7
|
-
import {
|
|
8
|
-
buildDefaultProjectContext,
|
|
9
|
-
buildTemplateContext,
|
|
10
|
-
validateContext
|
|
11
|
-
} from '../core/context.js';
|
|
12
|
-
import type { TemplateType } from '../core/types.js';
|
|
13
|
-
|
|
14
|
-
test('Context - Build Default Context', async (t) => {
|
|
15
|
-
await t.test('should create valid default context', () => {
|
|
16
|
-
const context = buildDefaultProjectContext(
|
|
17
|
-
'MyApp',
|
|
18
|
-
'com.example.myapp',
|
|
19
|
-
'./my-project',
|
|
20
|
-
'kotlin-compose' as TemplateType,
|
|
21
|
-
{ git: true, readme: true }
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
assert.strictEqual(context.appName, 'MyApp');
|
|
25
|
-
assert.strictEqual(context.packageName, 'com.example.myapp');
|
|
26
|
-
assert.strictEqual(context.template, 'kotlin-compose');
|
|
27
|
-
assert.strictEqual(context.language, 'kotlin');
|
|
28
|
-
assert.strictEqual(context.uiFramework, 'compose');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
await t.test('should set default features', () => {
|
|
32
|
-
const context = buildDefaultProjectContext(
|
|
33
|
-
'MyApp',
|
|
34
|
-
'com.example.myapp',
|
|
35
|
-
'./my-project',
|
|
36
|
-
'kotlin-xml' as TemplateType
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
assert.strictEqual(context.git, true);
|
|
40
|
-
assert.strictEqual(context.readme, true);
|
|
41
|
-
assert.strictEqual(context.androidX, true);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test('Context - Build Template Context', async (t) => {
|
|
46
|
-
await t.test('should build full template context', () => {
|
|
47
|
-
const baseContext = buildDefaultProjectContext(
|
|
48
|
-
'MyApp',
|
|
49
|
-
'com.example.myapp',
|
|
50
|
-
'./my-project',
|
|
51
|
-
'kotlin-compose' as TemplateType
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
const context = buildTemplateContext({
|
|
55
|
-
appName: baseContext.appName,
|
|
56
|
-
packageName: baseContext.packageName,
|
|
57
|
-
projectDirectory: baseContext.projectDirectory,
|
|
58
|
-
template: baseContext.template,
|
|
59
|
-
uiFramework: baseContext.uiFramework,
|
|
60
|
-
language: baseContext.language,
|
|
61
|
-
android: baseContext.android,
|
|
62
|
-
gradle: baseContext.gradle,
|
|
63
|
-
features: baseContext as unknown as Record<string, boolean>
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
assert.ok(context.appNameCamel);
|
|
67
|
-
assert.ok(context.appNamePascal);
|
|
68
|
-
assert.ok(context.appNameKebab);
|
|
69
|
-
assert.ok(context.appNameSnake);
|
|
70
|
-
assert.ok(context.packagePath);
|
|
71
|
-
assert.ok(context.year);
|
|
72
|
-
assert.ok(context.generatorVersion);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
await t.test('should generate correct app name transformations', () => {
|
|
76
|
-
const baseContext = buildDefaultProjectContext(
|
|
77
|
-
'MyAwesomeApp',
|
|
78
|
-
'com.example.myapp',
|
|
79
|
-
'./my-project',
|
|
80
|
-
'kotlin-compose' as TemplateType
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
const context = buildTemplateContext({
|
|
84
|
-
appName: baseContext.appName,
|
|
85
|
-
packageName: baseContext.packageName,
|
|
86
|
-
projectDirectory: baseContext.projectDirectory,
|
|
87
|
-
template: baseContext.template,
|
|
88
|
-
uiFramework: baseContext.uiFramework,
|
|
89
|
-
language: baseContext.language,
|
|
90
|
-
android: baseContext.android,
|
|
91
|
-
gradle: baseContext.gradle,
|
|
92
|
-
features: baseContext as unknown as Record<string, boolean>
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
assert.ok(context.appNamePascal.includes('Awesome'));
|
|
96
|
-
assert.ok(context.packagePath.includes('/'));
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test('Context - Validate Context', async (t) => {
|
|
101
|
-
await t.test('should accept valid context', () => {
|
|
102
|
-
const baseContext = buildDefaultProjectContext(
|
|
103
|
-
'MyApp',
|
|
104
|
-
'com.example.myapp',
|
|
105
|
-
'./my-project',
|
|
106
|
-
'kotlin-compose' as TemplateType
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
const result = validateContext(baseContext);
|
|
110
|
-
assert.strictEqual(result.valid, true);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
await t.test('should reject context with missing appName', () => {
|
|
114
|
-
const result = validateContext({
|
|
115
|
-
appName: '',
|
|
116
|
-
packageName: 'com.example.myapp',
|
|
117
|
-
template: 'kotlin-compose' as TemplateType
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
assert.strictEqual(result.valid, false);
|
|
121
|
-
assert.ok(result.errors.length > 0);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
await t.test('should reject context with missing packageName', () => {
|
|
125
|
-
const result = validateContext({
|
|
126
|
-
appName: 'MyApp',
|
|
127
|
-
packageName: '',
|
|
128
|
-
template: 'kotlin-compose' as TemplateType
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
assert.strictEqual(result.valid, false);
|
|
132
|
-
});
|
|
133
|
-
});
|