@lenne.tech/cli 0.0.124 → 0.0.125

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.
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ /**
13
+ * Extend toolbox with parseProperties() helper.
14
+ */
15
+ exports.default = (toolbox) => {
16
+ toolbox.parseProperties = (options) => __awaiter(void 0, void 0, void 0, function* () {
17
+ const { parameters: globalParameters, server: globalServer } = toolbox;
18
+ const { argProps = Object.keys(globalParameters.options || {}).filter(key => key.startsWith('prop')), objectsToAdd = [], parameters = globalParameters, referencesToAdd = [], server = globalServer, } = options || {};
19
+ // --- CLI Mode ---
20
+ if (argProps.length > 0) {
21
+ const { print } = toolbox;
22
+ // Count how many prop-name flags exist
23
+ const propNameFlags = argProps.filter(key => key.startsWith('prop-name'));
24
+ const hasMultipleProps = propNameFlags.length > 1;
25
+ // If multiple properties, all must have numeric indices
26
+ if (hasMultipleProps) {
27
+ const hasNonIndexed = propNameFlags.some(key => !key.match(/^prop-name-\d+$/));
28
+ if (hasNonIndexed) {
29
+ print.error('When adding multiple properties, all must use numeric indices (e.g., --prop-name-0, --prop-name-1)');
30
+ print.info('');
31
+ print.info('Example:');
32
+ print.info(' lt server addProp --type Module --element User \\');
33
+ print.info(' --prop-name-0 email --prop-type-0 string \\');
34
+ print.info(' --prop-name-1 age --prop-type-1 number');
35
+ throw new Error('Invalid property flags: Multiple properties require numeric indices');
36
+ }
37
+ }
38
+ // Extract index from prop key (e.g., 'prop-name-1' -> 1)
39
+ const extractIndex = (key, prefix) => {
40
+ const match = key.match(new RegExp(`^${prefix}-(\\d+)$`));
41
+ return match ? parseInt(match[1], 10) : -1;
42
+ };
43
+ // Build a map of index -> property data
44
+ const propDataByIndex = new Map();
45
+ for (const key of argProps) {
46
+ let index = -1;
47
+ let field = '';
48
+ if (key.startsWith('prop-name-')) {
49
+ index = extractIndex(key, 'prop-name');
50
+ field = 'name';
51
+ }
52
+ else if (key.startsWith('prop-type-')) {
53
+ index = extractIndex(key, 'prop-type');
54
+ field = 'type';
55
+ }
56
+ else if (key.startsWith('prop-nullable-')) {
57
+ index = extractIndex(key, 'prop-nullable');
58
+ field = 'nullable';
59
+ }
60
+ else if (key.startsWith('prop-array-')) {
61
+ index = extractIndex(key, 'prop-array');
62
+ field = 'isArray';
63
+ }
64
+ else if (key.startsWith('prop-enum-')) {
65
+ index = extractIndex(key, 'prop-enum');
66
+ field = 'enumRef';
67
+ }
68
+ else if (key.startsWith('prop-schema-')) {
69
+ index = extractIndex(key, 'prop-schema');
70
+ field = 'schema';
71
+ }
72
+ else if (key.startsWith('prop-reference-')) {
73
+ index = extractIndex(key, 'prop-reference');
74
+ field = 'reference';
75
+ }
76
+ if (index >= 0 && field) {
77
+ if (!propDataByIndex.has(index)) {
78
+ propDataByIndex.set(index, {
79
+ enumRef: null,
80
+ isArray: false,
81
+ name: '',
82
+ nullable: false,
83
+ reference: null,
84
+ schema: null,
85
+ type: 'string',
86
+ });
87
+ }
88
+ const propData = propDataByIndex.get(index);
89
+ const value = parameters.options[key];
90
+ if (field === 'nullable' || field === 'isArray') {
91
+ propData[field] = value === 'true';
92
+ }
93
+ else {
94
+ propData[field] = value;
95
+ }
96
+ }
97
+ }
98
+ // Convert map to props object
99
+ const props = {};
100
+ for (const propData of propDataByIndex.values()) {
101
+ if (!propData.name) {
102
+ continue;
103
+ }
104
+ props[propData.name] = propData;
105
+ }
106
+ return { objectsToAdd, props, referencesToAdd, refsSet: false, schemaSet: false };
107
+ }
108
+ // --- Interactive Mode ---
109
+ const result = yield server.addProperties({ objectsToAdd, referencesToAdd });
110
+ return {
111
+ objectsToAdd: result.objectsToAdd,
112
+ props: result.props,
113
+ referencesToAdd: result.referencesToAdd,
114
+ refsSet: result.refsSet,
115
+ schemaSet: result.schemaSet,
116
+ };
117
+ });
118
+ };
119
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UtcHJvcGVydGllcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHRlbnNpb25zL3BhcnNlLXByb3BlcnRpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFVQTs7R0FFRztBQUNILGtCQUFlLENBQUMsT0FBK0IsRUFBRSxFQUFFO0lBQ2pELE9BQU8sQ0FBQyxlQUFlLEdBQUcsQ0FDeEIsT0FNQyxFQUMyQixFQUFFO1FBQzlCLE1BQU0sRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUN2RSxNQUFNLEVBQ0osUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDNUYsWUFBWSxHQUFHLEVBQUUsRUFDakIsVUFBVSxHQUFHLGdCQUFnQixFQUM3QixlQUFlLEdBQUcsRUFBRSxFQUNwQixNQUFNLEdBQUcsWUFBWSxHQUN0QixHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDbEIsbUJBQW1CO1FBQ25CLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsT0FBTyxDQUFDO1lBRTFCLHVDQUF1QztZQUN2QyxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzFFLE1BQU0sZ0JBQWdCLEdBQUcsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFFbEQsd0RBQXdEO1lBQ3hELElBQUksZ0JBQWdCLEVBQUUsQ0FBQztnQkFDckIsTUFBTSxhQUFh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
@@ -0,0 +1,341 @@
1
+ ---
2
+ name: lt-cli
3
+ description: Expert assistance with lenne.tech CLI for NestJS/TypeScript backend development. Use when creating server modules, objects, or adding properties to NestJS backends. Generates correct lt server commands with proper --prop-name-X syntax. Helps with lt server module, lt server object, lt server addProp, and lt fullstack init commands.
4
+ ---
5
+
6
+ # LT CLI Expert
7
+
8
+ You are an expert in the lenne.tech CLI tool for NestJS/TypeScript backend development. When this skill is active, help users generate correct LT CLI commands and work efficiently with the framework.
9
+
10
+ ## Available Commands
11
+
12
+ ### 1. Create Server Module
13
+ **Command**: `lt server module` (alias: `lt server m`)
14
+
15
+ Creates a complete NestJS module with model, service, controller/resolver, and DTOs.
16
+
17
+ **Non-interactive syntax**:
18
+ ```bash
19
+ lt server module --name <ModuleName> --controller <Rest|GraphQL|Both> [property-flags]
20
+ ```
21
+
22
+ **Property flags** (multiple properties with different indices):
23
+ - `--prop-name-X <name>` - Property name (X = 0, 1, 2...)
24
+ - `--prop-type-X <type>` - string, number, boolean, ObjectId, Json, Date, etc.
25
+ - `--prop-nullable-X <true|false>` - Optional property
26
+ - `--prop-array-X <true|false>` - Array type
27
+ - `--prop-enum-X <EnumName>` - Enum reference
28
+ - `--prop-schema-X <SchemaName>` - Object/schema reference
29
+ - `--prop-reference-X <RefName>` - Reference name for ObjectId
30
+ - `--skipLint` - Skip lint prompt
31
+
32
+ **Example**:
33
+ ```bash
34
+ lt server module --name Post --controller GraphQL \
35
+ --prop-name-0 title --prop-type-0 string \
36
+ --prop-name-1 content --prop-type-1 string --prop-nullable-1 true \
37
+ --prop-name-2 author --prop-type-2 ObjectId --prop-reference-2 User \
38
+ --prop-name-3 tags --prop-type-3 string --prop-array-3 true
39
+ ```
40
+
41
+ ### 2. Add Properties to Existing Module/Object
42
+ **Command**: `lt server addProp` (alias: `lt server ap`)
43
+
44
+ Adds properties to existing modules or objects, updating model and input files.
45
+
46
+ **Non-interactive syntax**:
47
+ ```bash
48
+ lt server addProp --type <Module|Object> --element <name> [property-flags]
49
+ ```
50
+
51
+ **Example**:
52
+ ```bash
53
+ lt server addProp --type Module --element User \
54
+ --prop-name-0 email --prop-type-0 string \
55
+ --prop-name-1 age --prop-type-1 number --prop-nullable-1 true
56
+ ```
57
+
58
+ ### 3. Create Server Object
59
+ **Command**: `lt server object` (alias: `lt server o`)
60
+
61
+ Creates reusable data structures (objects) for embedding in modules.
62
+
63
+ **Non-interactive syntax**:
64
+ ```bash
65
+ lt server object --name <ObjectName> [property-flags] [--skipLint]
66
+ ```
67
+
68
+ **Example**:
69
+ ```bash
70
+ lt server object --name Address \
71
+ --prop-name-0 street --prop-type-0 string \
72
+ --prop-name-1 city --prop-type-1 string \
73
+ --prop-name-2 zipCode --prop-type-2 string
74
+ ```
75
+
76
+ ### 4. Initialize Fullstack Workspace
77
+ **Command**: `lt fullstack init` (alias: `lt full init`)
78
+
79
+ Creates complete fullstack workspace with frontend and backend.
80
+
81
+ **Non-interactive syntax**:
82
+ ```bash
83
+ lt fullstack init --name <WorkspaceName> --frontend <angular|nuxt> --git <true|false> --git-link <GitURL>
84
+ ```
85
+
86
+ **Example**:
87
+ ```bash
88
+ lt fullstack init --name MyApp --frontend angular --git true --git-link https://github.com/user/repo.git
89
+ ```
90
+
91
+ ## Critical Rules for Command Generation
92
+
93
+ ### 1. Index-Based Property Flags
94
+ Always use numbered indices for property flags:
95
+ ```bash
96
+ # CORRECT
97
+ --prop-name-0 title --prop-type-0 string \
98
+ --prop-name-1 content --prop-type-1 string
99
+
100
+ # WRONG - Don't use sequential arrays
101
+ --prop-name title --prop-type string
102
+ ```
103
+
104
+ ### 2. Match Indices Across Flags
105
+ All flags for one property must use the same index:
106
+ ```bash
107
+ # CORRECT
108
+ --prop-name-1 company --prop-type-1 string --prop-nullable-1 false
109
+
110
+ # WRONG - Mixed indices
111
+ --prop-name-1 company --prop-type-0 string --prop-nullable-2 false
112
+ ```
113
+
114
+ ### 3. ObjectId References
115
+ Always include `--prop-reference-X` with ObjectId type:
116
+ ```bash
117
+ --prop-name-0 author --prop-type-0 ObjectId --prop-reference-0 User
118
+ ```
119
+
120
+ ### 4. Schema/Object Properties
121
+ Use `--prop-schema-X` for embedding objects:
122
+ ```bash
123
+ --prop-name-0 address --prop-schema-0 Address
124
+ ```
125
+
126
+ ### 5. Boolean Values
127
+ Use lowercase string literals:
128
+ ```bash
129
+ --prop-nullable-0 true # CORRECT
130
+ --prop-nullable-0 True # WRONG
131
+ --prop-nullable-0 TRUE # WRONG
132
+ ```
133
+
134
+ ## Property Types Reference
135
+
136
+ ### Primitive Types
137
+ - `string` - Text values
138
+ - `number` - Numeric values
139
+ - `boolean` - True/false
140
+ - `bigint` - Large integers
141
+ - `Date` - Date/time values
142
+
143
+ ### Special Types
144
+ - `ObjectId` - MongoDB reference (requires `--prop-reference-X`)
145
+ - `Json` - JSON data for flexible metadata
146
+ - Custom objects (requires `--prop-schema-X`)
147
+ - Custom enums (requires `--prop-enum-X`) - **Note: CLI generates the reference, but you must create the enum file manually afterwards**
148
+
149
+ ### Modifiers
150
+ - `--prop-nullable-X true` - Makes property optional
151
+ - `--prop-array-X true` - Makes property an array type
152
+
153
+ ## Common Patterns
154
+
155
+ ### User Authentication
156
+ ```bash
157
+ lt server module --name User --controller Both \
158
+ --prop-name-0 email --prop-type-0 string \
159
+ --prop-name-1 username --prop-type-1 string \
160
+ --prop-name-2 roles --prop-type-2 string --prop-array-2 true \
161
+ --prop-name-3 verified --prop-type-3 boolean
162
+ ```
163
+
164
+ ### Blog Post with Relationships
165
+ ```bash
166
+ lt server module --name Post --controller GraphQL \
167
+ --prop-name-0 title --prop-type-0 string \
168
+ --prop-name-1 content --prop-type-1 string \
169
+ --prop-name-2 author --prop-type-2 ObjectId --prop-reference-2 User \
170
+ --prop-name-3 tags --prop-type-3 string --prop-array-3 true \
171
+ --prop-name-4 published --prop-type-4 boolean
172
+ ```
173
+
174
+ ### E-commerce Product
175
+ ```bash
176
+ lt server module --name Product --controller Both \
177
+ --prop-name-0 name --prop-type-0 string \
178
+ --prop-name-1 description --prop-type-1 string --prop-nullable-1 true \
179
+ --prop-name-2 price --prop-type-2 number \
180
+ --prop-name-3 stock --prop-type-3 number \
181
+ --prop-name-4 category --prop-enum-4 ProductCategoryEnum \
182
+ --prop-name-5 metadata --prop-type-5 Json --prop-nullable-5 true
183
+ ```
184
+
185
+ ### Nested Object Pattern
186
+ ```bash
187
+ # First create the object
188
+ lt server object --name Address \
189
+ --prop-name-0 street --prop-type-0 string \
190
+ --prop-name-1 city --prop-type-1 string \
191
+ --prop-name-2 country --prop-type-2 string
192
+
193
+ # Then use it in a module
194
+ lt server addProp --type Module --element User \
195
+ --prop-name-0 address --prop-schema-0 Address
196
+ ```
197
+
198
+ ## Project Structure
199
+
200
+ The CLI expects this structure:
201
+ ```
202
+ src/
203
+ server/
204
+ modules/
205
+ <module-name>/
206
+ <module-name>.model.ts # MongoDB schema
207
+ <module-name>.service.ts # Business logic
208
+ <module-name>.controller.ts # REST controller
209
+ <module-name>.resolver.ts # GraphQL resolver
210
+ <module-name>.module.ts # NestJS module
211
+ inputs/
212
+ <module-name>.input.ts # Update DTO
213
+ <module-name>-create.input.ts # Create DTO
214
+ outputs/
215
+ find-and-count-<module-name>s-result.output.ts
216
+ common/
217
+ objects/
218
+ <object-name>/
219
+ <object-name>.object.ts
220
+ <object-name>.input.ts
221
+ <object-name>-create.input.ts
222
+ ```
223
+
224
+ ## Generated Code Features
225
+
226
+ ### Model Files (.model.ts)
227
+ - MongoDB schema with `@Prop()` decorator
228
+ - `@UnifiedField()` decorator for GraphQL/REST
229
+ - Mongoose schema definition
230
+ - TypeScript typing with proper suffixes
231
+
232
+ ### Input Files (.input.ts / -create.input.ts)
233
+ - `@UnifiedField()` decorator
234
+ - Validation decorators
235
+ - TypeScript typing
236
+ - Generic support for references
237
+
238
+ ### Service Files (.service.ts)
239
+ - CRUD operations
240
+ - Pagination support
241
+ - Reference handling
242
+ - Business logic structure
243
+
244
+ ### Controller/Resolver Files
245
+ - REST endpoints (controller)
246
+ - GraphQL queries/mutations (resolver)
247
+ - Proper authentication guards
248
+ - DTO validation
249
+
250
+ ## Troubleshooting
251
+
252
+ ### Property Index Mismatch
253
+ **Symptom**: Properties not created correctly or values mixed up
254
+ **Cause**: Using wrong indices (e.g., `--prop-name-1` with `--prop-type-0`)
255
+ **Solution**: Ensure all flags for one property use the same index
256
+
257
+ ### ObjectId Without Reference
258
+ **Symptom**: TypeScript errors about missing reference
259
+ **Cause**: Using `ObjectId` type without `--prop-reference-X`
260
+ **Solution**: Always pair ObjectId with reference:
261
+ ```bash
262
+ --prop-type-0 ObjectId --prop-reference-0 User
263
+ ```
264
+
265
+ ### Module Already Exists
266
+ **Symptom**: Error that module directory exists
267
+ **Solution**: Use `lt server addProp` instead to add to existing modules
268
+
269
+ ### Empty Property Lists
270
+ **Symptom**: "Cannot read properties of undefined"
271
+ **Status**: Fixed in latest version
272
+ **Solution**: Update to latest CLI version
273
+
274
+ ## Best Practices
275
+
276
+ 1. **Plan relationships first**: Sketch entity relationships before generating
277
+ 2. **Create objects for reusable structures**: Don't duplicate data structures
278
+ 3. **Use meaningful names**: PascalCase for modules/objects, camelCase for properties
279
+ 4. **Start with one API type**: Use Rest or GraphQL, add Both later if needed
280
+ 5. **Create enum files after generation**: CLI generates enum references, you create the actual enum files manually afterwards in `src/server/common/enums/`
281
+ 6. **Mark truly optional fields**: Only use nullable for genuinely optional data
282
+ 7. **Use JSON for extensibility**: Metadata and flexible fields work well as JSON
283
+ 8. **Run lint after generation**: Always run lint fix for code quality
284
+ 9. **Test incrementally**: Generate one module, test, then continue
285
+ 10. **Version control**: Commit after successful generation
286
+
287
+ ## Working with This Skill
288
+
289
+ When helping users:
290
+
291
+ 1. **Clarify requirements**: Ask about API type (REST/GraphQL/Both), relationships, data types
292
+ 2. **Suggest architecture**: Recommend objects for shared structures, modules for entities
293
+ 3. **Generate complete commands**: Include all necessary flags with correct syntax
294
+ 4. **Explain side effects**: Describe what files will be created and where
295
+ 5. **Provide next steps**: Suggest related modules, testing, or additional properties
296
+
297
+ ### Example Response Pattern
298
+
299
+ User: "Create a Task module with title, description, due date, and assignee"
300
+
301
+ Your response:
302
+ ```bash
303
+ # First ensure User module exists, then create Task module
304
+ lt server module --name Task --controller Both \
305
+ --prop-name-0 title --prop-type-0 string \
306
+ --prop-name-1 description --prop-type-1 string --prop-nullable-1 true \
307
+ --prop-name-2 dueDate --prop-type-2 Date --prop-nullable-2 true \
308
+ --prop-name-3 assignee --prop-type-3 ObjectId --prop-reference-3 User \
309
+ --prop-name-4 status --prop-enum-4 TaskStatusEnum
310
+
311
+ # This creates:
312
+ # ✓ Task model with MongoDB schema
313
+ # ✓ Task service with CRUD operations
314
+ # ✓ REST controller and GraphQL resolver
315
+ # ✓ Input DTOs for create/update
316
+
317
+ # Next steps:
318
+ # 1. Manually create TaskStatusEnum file in src/server/common/enums/task-status.enum.ts
319
+ # 2. Verify User module exists
320
+ # 3. Run lint fix
321
+ # 4. Add custom business logic to TaskService
322
+ ```
323
+
324
+ ## Integration Details
325
+
326
+ - Uses `ts-morph` for AST manipulation
327
+ - Integrates with `@lenne.tech/nest-server` package
328
+ - Generates `@UnifiedField()` decorators for dual REST/GraphQL support
329
+ - Handles `useDefineForClassFields` TypeScript config
330
+ - Automatically adds properties to `.model.ts`, `.input.ts`, and `-create.input.ts`
331
+ - Manages imports and decorators automatically
332
+
333
+ ## Important Notes
334
+
335
+ - CLI works from anywhere in project directory
336
+ - Automatically finds nearest `src/` directory
337
+ - Properties are added with proper TypeScript typing
338
+ - ObjectId properties become Reference/ReferenceInput in generated code
339
+ - The CLI prompts for lint fix after generation (use `--skipLint` to skip)
340
+ - Manual imports may be needed for references and schemas
341
+ - **Enum files must be created manually**: When using `--prop-enum-X`, the CLI generates the reference in your code, but you must create the actual enum file yourself afterwards in `src/server/common/enums/<enum-name>.enum.ts`